1
1
Fork 0
mirror of https://github.com/QB64Official/qb64.git synced 2024-07-08 06:45:16 +00:00

Implemented a better _CONNECTED

It is no longer confused by buffered data. However, it no longer makes
an explicit call to send()/recv(), so one of those must first fail to
signal the disconnection. This allows _CONNECTED to be used to check
if a GET/PUT succeeded (on the local end, anyway).
This commit is contained in:
Luke Ceddia 2016-02-03 15:42:57 +11:00
parent 264ad29f22
commit 992a74c7ee

View file

@ -23025,6 +23025,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){
int32 port;//connection to host & clients only int32 port;//connection to host & clients only
uint8 ip4[4];//connection to host only uint8 ip4[4];//connection to host only
uint8* hostname;//clients only uint8* hostname;//clients only
int connected;
}; };
void *tcp_host_open(int64 port){ void *tcp_host_open(int64 port){
@ -23059,6 +23060,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){
static tcp_connection *connection; static tcp_connection *connection;
connection=(tcp_connection*)calloc(sizeof(tcp_connection),1); connection=(tcp_connection*)calloc(sizeof(tcp_connection),1);
connection->socket=listeningSocket; connection->socket=listeningSocket;
connection->connected = -1;
return (void*)connection; return (void*)connection;
#elif defined(QB64_LINUX) #elif defined(QB64_LINUX)
struct addrinfo hints, *servinfo, *p; struct addrinfo hints, *servinfo, *p;
@ -23093,6 +23095,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){
tcp_connection *connection; tcp_connection *connection;
connection=(tcp_connection*)calloc(sizeof(tcp_connection),1); connection=(tcp_connection*)calloc(sizeof(tcp_connection),1);
connection->socket=sockfd; connection->socket=sockfd;
connection->connected = -1;
return (void*)connection; return (void*)connection;
#else #else
return NULL; return NULL;
@ -23147,6 +23150,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){
connection=(tcp_connection*)calloc(sizeof(tcp_connection),1); connection=(tcp_connection*)calloc(sizeof(tcp_connection),1);
connection->socket=theSocket; connection->socket=theSocket;
connection->port=port; connection->port=port;
connection->connected = -1;
connection->hostname=(uint8*)malloc(strlen((char*)host)+1); connection->hostname=(uint8*)malloc(strlen((char*)host)+1);
memcpy(connection->hostname,host,strlen((char*)host)+1); memcpy(connection->hostname,host,strlen((char*)host)+1);
return (void*)connection; return (void*)connection;
@ -23177,6 +23181,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){
connection=(tcp_connection*)calloc(sizeof(tcp_connection),1); connection=(tcp_connection*)calloc(sizeof(tcp_connection),1);
connection->socket=sockfd; connection->socket=sockfd;
connection->port=port; connection->port=port;
connection->connected = -1;
connection->hostname=(uint8*)malloc(strlen((char*)host)+1); connection->hostname=(uint8*)malloc(strlen((char*)host)+1);
memcpy(connection->hostname,host,strlen((char*)host)+1); memcpy(connection->hostname,host,strlen((char*)host)+1);
return (void*)connection; return (void*)connection;
@ -23207,6 +23212,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){
connection->socket=new_socket; connection->socket=new_socket;
//IPv4: port,port,ip,ip,ip,ip //IPv4: port,port,ip,ip,ip,ip
connection->port=*((uint16*)sa.sa_data); connection->port=*((uint16*)sa.sa_data);
connection->connected = -1;
*((uint32*)(connection->ip4))=*((uint32*)(sa.sa_data+2)); *((uint32*)(connection->ip4))=*((uint32*)(sa.sa_data+2));
return (void*)connection; return (void*)connection;
#elif defined(QB64_LINUX) #elif defined(QB64_LINUX)
@ -23223,6 +23229,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){
tcp_connection *connection; tcp_connection *connection;
connection=(tcp_connection*)calloc(sizeof(tcp_connection),1); connection=(tcp_connection*)calloc(sizeof(tcp_connection),1);
connection->socket=fd; connection->socket=fd;
connection->connected = -1;
//IPv4: port,port,ip,ip,ip,ip //IPv4: port,port,ip,ip,ip,ip
connection->port=*((uint16*)remote_addr.sa_data); connection->port=*((uint16*)remote_addr.sa_data);
*((uint32*)(connection->ip4))=*((uint32*)(remote_addr.sa_data+2)); *((uint32*)(connection->ip4))=*((uint32*)(remote_addr.sa_data+2));
@ -23258,11 +23265,13 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){
while(total < bytes) { while(total < bytes) {
n = send(tcp->socket, (char*)(offset + total), bytesleft, 0); n = send(tcp->socket, (char*)(offset + total), bytesleft, 0);
if (n == -1) break; if (n < 0) {
tcp->connected = 0;
return;
}
total += n; total += n;
bytesleft -= n; bytesleft -= n;
} }
//if (n == -1) error occured.
#else #else
#endif #endif
} }
@ -23313,28 +23322,29 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){
expand_and_retry: expand_and_retry:
//expand buffer if 'in' stream is full //expand buffer if 'in' stream is full
//also guarantees that bytes requested from recv() is not 0
if (stream->in_size==stream->in_limit){ if (stream->in_size==stream->in_limit){
stream->in_limit*=2; stream->in=(uint8*)realloc(stream->in,stream->in_limit); stream->in_limit*=2; stream->in=(uint8*)realloc(stream->in,stream->in_limit);
} }
bytes = recv(tcp->socket,(char*)(stream->in+stream->in_size), bytes = recv(tcp->socket,(char*)(stream->in+stream->in_size),
stream->in_limit-stream->in_size, stream->in_limit-stream->in_size,
0); 0);
if (bytes < 0) { //some kind of error
#ifdef QB64_WINDOWS #ifdef QB64_WINDOWS
if (bytes==SOCKET_ERROR){ if (WSAGetLastError() != WSAEWOULDBLOCK) tcp->connected = 0; //fatal error
static ptrszint e;
e=WSAGetLastError();
return;
}
#else #else
if (bytes == -1) return; if (errno != EAGAIN && errno != EWOULDBLOCK) tcp->connected = 0;
#endif #endif
if (bytes<=0) return; }
stream->in_size+=bytes; else if (bytes == 0) { //graceful shutdown occured
tcp->connected = 0;
}
if (stream->in_size==stream->in_limit) goto expand_and_retry; else {
stream->in_size+=bytes;
if (stream->in_size==stream->in_limit) goto expand_and_retry;
}
#else #else
#endif #endif
} }
@ -23620,23 +23630,11 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){
} }
int32 tcp_connected (void *connection){ int32 tcp_connected (void *connection){
static tcp_connection *tcp=(tcp_connection*)connection; tcp_connection *tcp=(tcp_connection*)connection;
#if !defined(DEPENDENCY_SOCKETS) #if !defined(DEPENDENCY_SOCKETS)
return 0; return 0;
#elif defined(QB64_WINDOWS) #elif defined(QB64_WINDOWS) || defined(QB64_LINUX)
char buf; return tcp->connected;
int length=recv(tcp->socket, &buf, 0, 0);
int nError=WSAGetLastError();
if(nError!=WSAEWOULDBLOCK&&nError!=0)
{
return 0;
}
if (nError==0){
if (length==0) return 0;
}
return -1;
#elif defined(QB64_LINUX)
return -1;
#else #else
return 0; return 0;
#endif #endif