summaryrefslogtreecommitdiff
path: root/Runtime/Network/Sockets.h
blob: 6a4f5d79ce081cd1dfbd3dcce6fa3a256064552f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#ifndef RUNTIME_NETWORK_SOCKETS_H
#define RUNTIME_NETWORK_SOCKETS_H

#include "SocketConsts.h"

#if ENABLE_SOCKETS

#include "Runtime/Utilities/NonCopyable.h"

//
// Socket implementations, all sockets are by default non-blocking.
// Metro: the implementation of this is located in PlatformDependent\MetroPlayer\MetroSocket.cpp
//
class Socket : public NonCopyable
{
#if UNITY_WINRT
#	define UNITY_SOCKET_STATIC_ERROR_STATE
#else
#	define UNITY_SOCKET_STATIC_ERROR_STATE static
#endif // UNITY_WINRT

public:
	static TSocketHandle Connect(const char* ip, unsigned short port, time_t timeoutMS = 4000, bool polling = false, bool logConnectError = true);
#if !UNITY_WINRT
	static int Connect(const sockaddr* addr, socklen_t addr_len, time_t timeoutMS = 4000, bool polling = false, bool logConnectError = true);
#endif
	static int Close(TSocketHandle socketHandle);

	static int PollAsyncConnection(TSocketHandle socketHandle, time_t timeoutMS = 0);
	UNITY_SOCKET_STATIC_ERROR_STATE bool CheckError(int result, const char* msg = NULL, int valid_state = 0, int identifier = 0);
	UNITY_SOCKET_STATIC_ERROR_STATE bool WouldBlockError();

	bool WaitForAvailableSendBuffer(time_t timeoutMS);
	bool WaitForAvailableRecvData(time_t timeoutMS);

protected:
	Socket(TSocketHandle socketHandle);
	Socket(int domain, int type, int protocol);
	virtual ~Socket();

	int SetSocketOption(int level, int option, void* value, size_t value_len);
	int SetSocketOption(int level, int option, bool value);

	bool SetReuseAddress(bool reuse);

	int Send(const void* data, size_t data_len, SendUserData* userData = NULL);
	int Recv(void* data, size_t data_len, RecvUserData* userData = NULL);
	
	bool SetIgnoreSIGPIPE(bool ignore);
	bool SetBlocking(bool block);

protected:
	TSocketHandle m_SocketHandle;
	int m_SendRecvFlags;
	volatile int m_SocketError;

private:
	static bool SetBlocking(TSocketHandle socketHandle, bool block);

	UNITY_SOCKET_STATIC_ERROR_STATE int GetError();
	UNITY_SOCKET_STATIC_ERROR_STATE int SetError(int error);

#undef UNITY_SOCKET_STATIC_ERROR_STATE
};

 
#if UNITY_WINRT
namespace UnityPlayer
{
	[Windows::Foundation::Metadata::WebHostHidden]
	public ref class StreamListenerContext sealed
	{
	public:
		StreamListenerContext( Windows::Networking::HostName^ hostname, Platform::String^ serviceName );
		void OnConnection( Windows::Networking::Sockets::StreamSocketListener^ streamSocket, Windows::Networking::Sockets::StreamSocketListenerConnectionReceivedEventArgs^ args);
		Windows::Networking::Sockets::StreamSocketListener^ GetStreamSocket() { return m_listener; }
		Windows::Networking::Sockets::StreamSocket^ GetConnectionSocket() { return m_connectionSocket; }
		void Bind();

	private:
		Windows::Networking::Sockets::StreamSocketListener^ m_listener;
		Windows::Networking::Sockets::StreamSocket^ m_connectionSocket;
		Windows::Networking::HostName^ m_hostname;
		Platform::String^ m_port;
	};
}
#endif // UNITY_WINRT


#endif // ENABLE_SOCKETS

#endif // RUNTIME_NETWORK_SOCKETS_H