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