+#define _Noreturn
+
namespace net;
#include <stdarg.h>
#if defined(__WIN32__)
#define WIN32_LEAN_AND_MEAN
+#define String _String
#include <winsock.h>
-static WSADATA wsaData;
+#undef String
+#define SOCKLEN_TYPE int
#elif defined(__unix__) || defined(__APPLE__)
default:
+#define SOCKLEN_TYPE socklen_t
+#define set _set
#define uint _uint
#include <sys/time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <arpa/inet.h>
+#undef set
#undef uint
private:
import "network"
+#ifdef __ANDROID__
+// TOFIX:
+#undef ntohs
+#undef htons
+#define ntohs(x) (x)
+#define htons(x) (x)
+#endif
+
#define GETLEDWORD(b) (uint32)(((b)[3] << 24) | ((b)[2] << 16) | ((b)[1] << 8) | (b)[0])
#define PUTLEDWORD(b, d) \
};
static class SocketConnectThread : Thread
-{
+{
Socket socket;
-
+
uint Main()
{
bool result = false;
{
network.mutex.Wait();
strcpy(socket.inetAddress, inet_ntoa(socket.a.sin_addr));
- socket.inetPort = ntohs(socket.a.sin_port);
+ socket.inetPort = ntohs(socket.a.sin_port);
network.mutex.Release();
- if(socket.OnEstablishConnection(socket.s))
+ if(socket.OnEstablishConnection((int)socket.s))
{
network.mutex.Wait();
result = true;
#endif
if(result && !socket.destroyed)
socket._connected = 1;
- else
+ else if(socket._connected == -2)
socket._connected = -1;
#ifdef DEBUG_SOCKETS
{
SOCKET s;
SOCKADDR_IN a;
- int addrLen = sizeof(a);
-
+ SOCKLEN_TYPE addrLen = sizeof(a);
+
value.accepted = true;
s = accept(value.s,(SOCKADDR *)&a, &addrLen);
if(s != -1)
address = null;
this.a = a;
strcpy(inetAddress, inet_ntoa(this.a.sin_addr));
- inetPort = ntohs(a.sin_port);
+ inetPort = ntohs(a.sin_port);
this.s = s;
service = value;
connectThread = null;
network.mutex.Wait();
FD_SET(s, &network.exceptSet);
FD_SET(s, &network.readSet);
- if(s >= network.ns)
+ if(s >= network.ns)
{
- network.ns = s+1;
+ network.ns = (int)(s+1);
network.socketsSemaphore.Release();
}
network.mutex.Release();
get { return this ? service : null; }
};
- property char * inetAddress { get { return (char *)inetAddress; } };
+ property const char * inetAddress { get { return (char *)inetAddress; } };
property int inetPort { get { return inetPort; } }
property Socket next { get { return next; } };
property bool connected { get { return _connected == 1 || _connected == -2; } };
uint size = GETLEDWORD((byte *)&packet.size);
if(count >= size)
{
+ byte * tempBuffer = null;
if(size)
{
- CopyBytes(recvBuffer, recvBuffer + size, recvBytes - size);
+ if(recvBytes - size)
+ {
+ tempBuffer = new byte[size];
+ packet = (Packet)tempBuffer;
+ memcpy(tempBuffer, buffer, size);
+ memmove(recvBuffer, recvBuffer + size, recvBytes - size);
+ }
recvBytes -= size;
}
OnReceivePacket(packet);
+ delete tempBuffer;
return 0;
- }
+ }
}
return 0;
}
virtual void OnDisconnect(int code);
virtual void OnReceivePacket(Packet packet);
- bool Connect(char * address, int port)
+ bool Connect(const char * address, int port)
{
bool result = false;
#if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
if(!disconnected)
{
+ if(_connected == -2 && connectThread)
+ {
+ incref this;
+ network.mutex.Release();
+ connectThread.Wait();
+ delete connectThread;
+ network.mutex.Wait();
+ _refCount--;
+ }
disconnected = true;
if(!service)
{
- if(_connected == -1/* != 1*/)
- {
- network.connectSockets.Remove(this);
- _connected = 0;
- }
- else if(_connected)
- {
- network.sockets.Remove(this);
- _connected = 0;
- }
+ if(_connected)
+ ((_connected == -1 || _connected == -2) ? network.connectSockets : network.sockets).Remove(this);
}
else
{
if(s == network.ns - 1)
Network_DetermineMaxSocket();
-
+
if(s != -1)
{
FD_CLR(s, &network.readSet);
//if(_refCount > 1)
/*if(_refCount >= 1)
_refCount--;*/
- network.mutex.Release();
shutdown(s, 2);
if(!wasDisconnected)
delete this;
+
+ network.mutex.Release();
#endif
}
}
// --- Transfer ---
- bool Send(void * buffer, int size)
+ bool Send(const void * buffer, int size)
{
#if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
if(this)
fd_set ws, es;
if(s != -1 && ((type == tcp && (count = SendData(buffer, size, 0))) ||
- (type == udp && (count = sendto(s, buffer, size,0, (SOCKADDR *)&a, sizeof(a))))))
+ (type == udp && (count = (int)sendto(s, buffer, size,0, (SOCKADDR *)&a, sizeof(a))))))
{
#if defined(__WIN32__)
int error = WSAGetLastError();
#endif
{
//Print("~");
- }
+ }
// This is what was making eCom jam...
// select(s+1, null, &ws, &es, null);
return false;
}
- bool SendString(char * string)
+ bool SendString(const char * string)
{
- return Send(string, strlen(string));
+ return Send(string, (int)strlen(string));
}
- bool Sendf(char * format, ...)
+ bool Sendf(const char * format, ...)
{
bool result;
va_list args;
char string[MAX_F_STRING];
va_start(args, format);
- vsprintf(string,format,args);
- result = Send(string, strlen(string));
+ vsnprintf(string, sizeof(string), format, args);
+ string[sizeof(string)-1] = 0;
+ result = Send(string, (int)strlen(string));
va_end(args);
return result;
}
- bool DatagramConnect(char * sendAddress, int port)
+ bool DatagramConnect(const char * sendAddress, int port)
{
SOCKET s = socket(AF_INET,SOCK_DGRAM,0);
if(s != -1)
bool DatagramHost(int port)
{
SOCKET s = socket(AF_INET,SOCK_DGRAM,0);
- if(s != -1)
+ if(s != -1 && !_connected)
{
SOCKADDR_IN a;
bool val = true;
FD_CLR(s, &network.writeSet);
FD_SET(s, &network.readSet);
FD_SET(s, &network.exceptSet);
- if(s >= network.ns)
+ if(s >= network.ns)
{
- network.ns = s+1;
+ network.ns = (int)(s+1);
network.socketsSemaphore.Release();
}
network.mutex.Release();
virtual int ReceiveData(byte * buffer, int count, uint flags)
{
- return (int)recv(s, buffer, count, flags);
+ return (int)recv(s, (char *)buffer, count, flags);
}
- virtual int SendData(byte * buffer, int count, uint flags)
+ virtual int SendData(const byte * buffer, int count, uint flags)
{
- return (int)send(s, buffer, count, flags);
+ return (int)send(s, (const char *)buffer, count, flags);
}
virtual bool OnEstablishConnection(int s);
~Socket()
{
_refCount = MAXINT;
- Free();
+ Free(true);
_refCount = 0;
}
#ifndef ECERE_NONET
- void Free()
+ void Free(bool mustLock)
{
SOCKET s = this.s;
- network.mutex.Wait();
- if(!service)
+ if(mustLock) network.mutex.Wait();
+
+ if(!service && _connected)
{
- if(_connected == -1/* != 1*/)
- {
- network.connectSockets.Remove(this);
- _connected = 0;
- }
- else if(_connected)
- {
- network.sockets.Remove(this);
- _connected = 0;
- }
+ ((_connected == -1 || _connected == -2) ? network.connectSockets : network.sockets).Remove(this);
+ _connected = 0;
}
if(!disconnected)
service = null;
_connected = 0;
}
-
+
if(s != -1) { closesocket(s); this.s = -1; }
delete address;
- delete recvBuffer;
+ delete recvBuffer;
recvBufferSize = 0;
recvBytes = 0;
- if(s != -1)
+ if(s != -1)
{
FD_CLR(s, &network.readSet);
FD_CLR(s, &network.writeSet);
// COMMENTED THIS OUT SINCE IT WAS INVALIDATING PROTECTION FOR HTTP FILE CONNECTION REUSE...
// WATCH FOR LEAKS IN OTHER PROJECTS?
//if(_refCount > 1) _refCount--;
- network.mutex.Release();
+ if(mustLock) network.mutex.Release();
}
void _Disconnect(DisconnectCode code)
network.mutex.Wait();
disconnectCode = code;
- Free();
+
+ Free(false);
delete this;
if(s == network.ns - 1)
network.mutex.Release();
}
- bool _Connect(SOCKET s, char * address, int port)
+ bool _Connect(SOCKET s, const char * address, int port)
{
bool result = false;
if(this)
_connected = -2;
FD_SET(s, &network.writeSet);
- if(s >= network.ns && !processAlone)
+ if(s >= network.ns && !processAlone)
{
- network.ns = s+1;
+ network.ns = (int)(s+1);
network.socketsSemaphore.Release();
}
connectThread = SocketConnectThread { socket = this };
if(_connected == -1 || destroyed)
{
_connected = 0;
-
+
if(s == network.ns - 1)
Network_DetermineMaxSocket();
#if 0
}
else
this.s = -1;
-
+
delete connectThread;
}
else
int count = 0;
result = true;
- if(recvBufferSize - recvBytes < MAX_RECEIVE)
+ if((int)recvBufferSize - recvBytes < MAX_RECEIVE)
{
recvBuffer = renew recvBuffer byte[recvBufferSize + MAX_RECEIVE];
recvBufferSize += MAX_RECEIVE;
}
-
+
if(FD_ISSET(s, rs) && disconnectCode == (DisconnectCode)-1)
{
if(type == tcp /*|| _connected*/)
count = ReceiveData(recvBuffer + recvBytes, recvBufferSize - recvBytes, 0);
else
{
- int len = sizeof(a);
- count = recvfrom(s, recvBuffer + recvBytes,
+ SOCKLEN_TYPE len = sizeof(a);
+ count = (int)recvfrom(s, (char *)recvBuffer + recvBytes,
recvBufferSize - recvBytes, 0, (SOCKADDR *)&a, &len);
strcpy(inetAddress, inet_ntoa(this.a.sin_addr));
inetPort = ntohs((uint16)a.sin_port);
}
}
- if(count > 0 || leftOver)
+ if(count > 0 || (leftOver && !count))
{
uint flushCount;
leftOver = false;
{
if(flushCount)
{
- CopyBytes(recvBuffer, recvBuffer + flushCount, recvBytes - flushCount);
+ memmove(recvBuffer, recvBuffer + flushCount, recvBytes - flushCount);
recvBytes -= flushCount;
}
else
public bool Process()
{
+ return ProcessTimeOut(0);
+ }
+
+ public bool ProcessTimeOut(Seconds timeOut)
+ {
bool gotEvent = false;
struct timeval tv = {0, 0};
+ struct timeval tvTO = {(uint)timeOut, (uint)((timeOut -(uint)timeOut)* 1000000)};
fd_set rs, ws, es;
int selectResult;
- if(disconnectCode > 0) return false;
+ if(disconnectCode > 0 && !leftOver) return false;
FD_ZERO(&rs);
FD_ZERO(&ws);
FD_ZERO(&es);
//FD_SET(s, &ws);
FD_SET(s, &es);
- selectResult = select(s+1, &rs, &ws, &es, leftOver ? &tv : null);
+ incref this;
+ selectResult = select((int)(s+1), &rs, &ws, &es, leftOver ? &tv : (timeOut ? &tvTO : null));
mutex.Wait();
if(s != -1 && _refCount && (leftOver || selectResult))
{
gotEvent |= ProcessSocket(&rs, &ws, &es);
}
mutex.Release();
+ delete this;
return gotEvent;
}
Thread connectThread;
DisconnectCode disconnectCode;
bool destroyed;
- int _connected;
+ int _connected; // -2: Initial value when calling Connect(), -1: Disconnected or otherwise destroyed while connecting, 1: succesfully connected, 0: no longer in any connect/sockets list
bool disconnected;
// Receiving Buffer