"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/Plugins/Qt/QTMSockets.cpp" between
TeXmacs-2.1.1-src.tar.gz and TeXmacs-2.1.2-src.tar.gz

About: GNU TeXmacs is a scientific editing platform designed to create beautiful technical documents using a wysiwyg interface.

QTMSockets.cpp  (TeXmacs-2.1.1-src):QTMSockets.cpp  (TeXmacs-2.1.2-src)
skipping to change at line 15 skipping to change at line 15
* COPYRIGHT : (C) 2015 Denis RAUX * COPYRIGHT : (C) 2015 Denis RAUX
******************************************************************************* *******************************************************************************
* This software falls under the GNU general public license version 3 or later. * This software falls under the GNU general public license version 3 or later.
* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
* in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>. * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
******************************************************************************/ ******************************************************************************/
#include "QTMSockets.hpp" #include "QTMSockets.hpp"
#include "scheme.hpp" #include "scheme.hpp"
#include "iterator.hpp" #include "iterator.hpp"
#include "analyze.hpp"
#ifndef OS_MINGW #ifndef OS_MINGW
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netdb.h> #include <netdb.h>
#include <stdint.h> #include <stdint.h>
#include <fcntl.h> #include <fcntl.h>
#include <arpa/inet.h>
#define CONNECT ::connect #define CONNECT ::connect
#define CLOSE(a) close(a) #define CLOSE(a) close(a)
#define WRITE(a, b, c) ::write(a, b, c) #define WRITE(a, b, c) ::write(a, b, c)
#define ERRNO errno #define ERRNO errno
#define ERRSOC(a) a #define ERRSOC(a) a
#define GETADDRINFO getaddrinfo #define GETADDRINFO getaddrinfo
#define FREEADDRINFO freeaddrinfo #define FREEADDRINFO freeaddrinfo
#define ADDRINFO addrinfo #define ADDRINFO addrinfo
#define SOCKET socket
#define RECV recv
#define GAI_STRERROR gai_strerror
#define BIND bind
#define LISTEN listen
#define ACCEPT accept
#define INET_NTOP inet_ntop
#else #else
#define CONNECT wsoc::connect #define CONNECT wsoc::connect
#define CLOSE(a) wsoc::closesocket(a) #define CLOSE(a) wsoc::closesocket(a)
#define WRITE(a, b, c) wsoc::send(a, b, c, 0) #define WRITE(a, b, c) wsoc::send(a, b, c, 0)
#define ERRNO wsoc::WSAGetLastError() #define ERRNO wsoc::WSAGetLastError()
#define ERRSOC(a) WSA##a #define ERRSOC(a) WSA##a
#define GETADDRINFO wsoc::getaddrinfo #define GETADDRINFO wsoc::getaddrinfo
#define FREEADDRINFO wsoc::freeaddrinfo #define FREEADDRINFO wsoc::freeaddrinfo
#define ADDRINFO wsoc::addrinfo #define ADDRINFO wsoc::addrinfo
#define SOCKET wsoc::socket
#define RECV wsoc::recv
#define GAI_STRERROR wsoc::gai_strerror
#define BIND wsoc::bind
#define LISTEN wsoc::listen
#define ACCEPT wsoc::accept
#define INET_NTOP wsoc::inet_ntop
#endif #endif
unsigned dbg_cnt; unsigned qtmsocket_debug_count;
int socket_link::nr_ids= 0;
int socket_basic::count= 0; int socket_basic::count= 0;
#ifdef OS_MINGW #ifdef OS_MINGW
wsoc::WSADATA socket_basic::wsadata; wsoc::WSADATA socket_basic::wsadata;
#endif #endif
string static string
show_addr (unsigned long a) { string_from_socket_address (SOCKADDR_STORAGE* sock) {
string s(12); static char tmp[128];
s << as_string (a & 0xff) << "."; a >>= 8; if (sock->ss_family == AF_INET) {
s << as_string (a & 0xff) << "."; a >>= 8; #ifdef OS_MINGW
s << as_string (a & 0xff) << "."; a >>= 8; return wsoc::inet_ntoa (((SOCKADDR_IN*) sock)->sin_addr);
s << as_string (a) ; #else
return s; if (inet_ntop (AF_INET, &(((sockaddr_in*) sock)->sin_addr),
tmp, sizeof(tmp)) == NULL)
return "";
return tmp;
#endif
}
if (sock->ss_family == AF_INET6) {
#if !defined (OS_MINGW) || (_WIN32_WINNT >= 0x0600)
if (INET_NTOP (AF_INET6, &(((SOCKADDR_IN6*) sock)->sin6_addr),
tmp, sizeof(tmp)) == NULL)
return "";
#else
return "";
#endif
return tmp;
}
return "";
} }
socket_basic::socket_basic (): st (ST_VOID) { socket_basic::socket_basic (): st (ST_VOID) {
#ifdef OS_MINGW #ifdef OS_MINGW
if (!count) { if (!count) {
using namespace wsoc; using namespace wsoc;
err=wsoc::WSAStartup (MAKEWORD (2,0), &wsadata); err= WSAStartup (MAKEWORD (2,0), &wsadata);
if (err) {st= ST_WSA; return;} if (err) {st= ST_WSA; return;}
} }
#endif #endif
count++; count++;
}; };
socket_basic::~socket_basic () { socket_basic::~socket_basic () {
if (count > 0) --count; if (count > 0) --count;
#ifdef OS_MINGW #ifdef OS_MINGW
if (!count) wsoc::WSACleanup (); if (!count) wsoc::WSACleanup ();
#endif #endif
}; };
socket_link::socket_link (int s, struct SOCKADDR_IN *addr): id (++nr_ids) { socket_link::socket_link (int s, SOCKADDR_STORAGE* addr) {
//cout << "Socket link [1] ~> " << id << LF; id++; sock= s; qsnr= NULL; qsnw= NULL;
sock= s; qsnr= NULL; qsnw= NULL;
if (st != ST_VOID) return; if (st != ST_VOID) return;
memcpy (&add, addr, sizeof(add)); memcpy (&add, addr, sizeof(add));
qsnr= tm_new <QSocketNotifier> (s, QSocketNotifier::Read); qsnr= tm_new<QSocketNotifier> (s, QSocketNotifier::Read);
qsnw= tm_new <QSocketNotifier> (s, QSocketNotifier::Write); qsnw= tm_new<QSocketNotifier> (s, QSocketNotifier::Write);
if (!qsnr || !qsnw) { err= ERRNO; st= ST_NOTIF; return; }
if (!qsnr || !qsnw) { err=ERRNO; st=ST_NOTIF; return; }
QObject::connect (qsnr, SIGNAL(activated(int)), QObject::connect (qsnr, SIGNAL(activated(int)),
this, SLOT(data_set_ready(int))); this, SLOT(data_set_ready(int)));
QObject::connect (qsnw, SIGNAL(activated(int)), QObject::connect (qsnw, SIGNAL(activated(int)),
this, SLOT(ready_to_send(int))); this, SLOT(ready_to_send(int)));
DBG_IO ("Socket Created fd=" << sock); DBG_IO ("Socket created with fd= " << sock);
st= ST_OK; st= ST_OK;
} }
socket_link::socket_link(string host, u_short port): id (++nr_ids) { socket_link::socket_link (string host, unsigned short port) {
//cout << "Socket link [2] ~> " << id << LF; ++id; qsnr= NULL; qsnw= NULL;
qsnr= NULL; qsnw= NULL;
if (st != ST_VOID) return; if (st != ST_VOID) return;
/* this original code used the deprecated function gethostbyname string host_tmp= host;
this was signaled in the tracker (#34182, #46726) if (starts (host, "[") && ends (host, "]"))
Below the functionality is implemented using getaddrinfo, host_tmp = host(1, N(host)-1);
c_string _host (host_tmp);
//Create socket
sock= NMSPC (socket (AF_INET , SOCK_STREAM , 0));
if (sock == -1) { err= errno; st= ST_SOCKET; return; }
// getting host
struct NMSPC (hostent) *hp= NMSPC (gethostbyname (as_charp (host)));
if (hp == NULL) { err= errno; st= ST_GETHOST; return; }
//Prepare the sockaddr_in structure
add.sin_family = AF_INET;
add.sin_addr.s_addr= *((unsigned long*)(hp->h_addr));
add.sin_port = NMSPC(htons(port));
if (CONNECT (sock, (struct SOCKADDR *) &add, sizeof (add))) {
err= errno; st= ST_CONNECTION; return; }
*/
c_string _host (host);
c_string _port (as_string (port)); c_string _port (as_string (port));
struct ADDRINFO hints; struct ADDRINFO hints;
struct ADDRINFO *result, *rp; struct ADDRINFO *result, *rp;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6, AF_INET for v4 only*/ hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; /* stream socket */ hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ hints.ai_flags = AI_PASSIVE;
hints.ai_protocol = 0; /* Any protocol */ hints.ai_protocol = 0;
hints.ai_canonname = NULL; hints.ai_canonname = NULL;
hints.ai_addr = NULL; hints.ai_addr = NULL;
hints.ai_next = NULL; hints.ai_next = NULL;
int x = GETADDRINFO (_host, _port, &hints, &result);
int x = GETADDRINFO(_host, _port, &hints, &result); if (x != 0) { err= ERRNO; st= ST_GETHOST; return; };
if (x != 0) { err= ERRNO; st= ST_GETHOST; return; };
for (rp = result; rp != NULL; rp = rp->ai_next) { for (rp = result; rp != NULL; rp = rp->ai_next) {
sock= NMSPC ( socket(rp->ai_family, rp->ai_socktype, sock= SOCKET (rp->ai_family, rp->ai_socktype,
rp->ai_protocol)); rp->ai_protocol);
if (sock == -1) if (sock < 0)
continue; continue;
if (CONNECT (sock, rp->ai_addr, rp->ai_addrlen) != -1)
if (CONNECT (sock, rp->ai_addr, rp->ai_addrlen) != -1) break;
break; /* Success */ CLOSE (sock);
CLOSE(sock);
}
if (rp == NULL) { /* No address succeeded */
err= ERRNO; st= ST_CONNECTION; return;
} }
if (rp == NULL) { err= ERRNO; st= ST_CONNECTION; return; }
FREEADDRINFO(result); /* No longer needed */ FREEADDRINFO (result);
#ifndef OS_MINGW
#ifndef OS_MINGW
if (fcntl (sock, F_SETFL, O_NONBLOCK) == -1) { if (fcntl (sock, F_SETFL, O_NONBLOCK) == -1) {
err= errno; st= ST_FCNTL; return; } err= errno; st= ST_FCNTL; return; }
#else #else
{ {
unsigned long flags = -1; using namespace wsoc;
if (wsoc::ioctlsocket (sock, FIONBIO, &flags) == SOCKET_ERROR) { u_long flags = -1;
if (ioctlsocket (sock, FIONBIO, &flags) == SOCKET_ERROR) {
err= ERRNO; st= ST_FCNTL; return; } err= ERRNO; st= ST_FCNTL; return; }
} }
#endif #endif
qsnr= tm_new <QSocketNotifier> (sock, QSocketNotifier::Read); qsnr= tm_new<QSocketNotifier> (sock, QSocketNotifier::Read);
qsnw= tm_new <QSocketNotifier> (sock, QSocketNotifier::Write); qsnw= tm_new<QSocketNotifier> (sock, QSocketNotifier::Write);
if (!qsnr || !qsnw) { err= ERRNO; st= ST_NOTIF; return; } if (!qsnr || !qsnw) { err= ERRNO; st= ST_NOTIF; return; }
QObject::connect (qsnr, SIGNAL (activated(int)), QObject::connect (qsnr, SIGNAL (activated(int)),
this, SLOT (data_set_ready(int))); this, SLOT (data_set_ready(int)));
qsnw->setEnabled (false); qsnw->setEnabled (false);
QObject::connect (qsnw, SIGNAL (activated(int)), QObject::connect (qsnw, SIGNAL (activated(int)),
this, SLOT (ready_to_send(int))); this, SLOT (ready_to_send(int)));
DBG_IO ("Socket Created fd=" << sock); DBG_IO ("Socket created with fd= " << sock);
st= ST_OK; st= ST_OK;
} }
socket_link::~socket_link() { socket_link::~socket_link() {
DBG_IO ("Socket closing fd=" << sock); DBG_IO ("Closing socket for fd= " << sock);
if (qsnr) { qsnr->disconnect (SIGNAL(activated(int))); tm_delete (qsnr); } if (qsnr) { qsnr->disconnect (SIGNAL(activated(int))); tm_delete (qsnr); }
if (qsnw) { qsnw->disconnect (SIGNAL(activated(int))); tm_delete (qsnw); } if (qsnw) { qsnw->disconnect (SIGNAL(activated(int))); tm_delete (qsnw); }
if (sock != -1) { CLOSE (sock); sock=-1;} if (sock != -1) { CLOSE (sock); sock=-1;}
st= ST_CLOSED; st= ST_CLOSED;
} }
string string
socket_link::start () { socket_link::start () {
string ret; string ret;
switch(st) { switch(st) {
case ST_OK: return ""; break; case ST_OK: return ""; break;
case ST_VOID: ret= "Socket not Initialised"; break; case ST_VOID: ret= "Socket not initialised"; break;
case ST_SOCKET: ret= "Error in opening socket"; break; case ST_SOCKET: ret= "Error in opening socket"; break;
case ST_FCNTL: ret= "Error in setting blocking mode"; break; case ST_FCNTL: ret= "Error in setting blocking mode"; break;
case ST_BIND: ret= "Error during bind"; break; case ST_BIND: ret= "Error during bind"; break;
case ST_LISTEN: ret= "Error during listen"; break; case ST_LISTEN: ret= "Error during listen"; break;
case ST_CONNECTION: ret= "Error during connect"; break; case ST_CONNECTION: ret= "Error during connect"; break;
case ST_GETHOST: ret= "Error in getting host"; break; case ST_GETHOST: ret= "Error in getting host"; break;
case ST_NOTIF: ret= "Error in setting notifier"; break; case ST_NOTIF: ret= "Error in setting notifier"; break;
default: ret= "No error message"; default: ret= "No error message";
} }
return ret * " errno:" * strerror(err); return ret * " errno: " * strerror(err);
} }
string& string&
socket_link::watch (int channel) { socket_link::watch (int channel) {
static string empty_string= ""; static string empty_string= "";
if (channel == LINK_OUT) return inbuf; if (channel == LINK_OUT) return inbuf;
else return empty_string; else return empty_string;
} }
string string
socket_link::read (int channel) { socket_link::read (int channel) {
DBG_IO ("Socket read size=" << N(inbuf)); DBG_IO ("Socket read size= " << N(inbuf));
if (channel == LINK_OUT && N(inbuf)) { if (channel == LINK_OUT && N(inbuf)) {
string r= inbuf; string r= inbuf;
inbuf= ""; inbuf= "";
return r; return r;
} }
else return ""; else return "";
} }
void void
socket_link::stop () { socket_link::stop () {
st= ST_HALTED; st= ST_HALTED;
emit disconnection(this); emit disconnection (this);
} }
void void
socket_link::data_set_ready (int s) { socket_link::data_set_ready (int s) {
char data[2048]; char data[2048];
qsnr->setEnabled(false); qsnr->setEnabled (false);
int lgdata= RECV(s, data, sizeof(data), 0);
int lgdata = NMSPC (recv (s , data , sizeof(data) , 0)); DBG_IO ("Socket incoming code= " << lgdata);
DBG_IO ("Socket incoming code=" << lgdata); if (lgdata == 0) {
if (lgdata == 0) {
DBG_IO ("Client disconnected"); DBG_IO ("Client disconnected");
stop (); stop ();
} }
else if (lgdata == -1) { else if (lgdata == -1) {
switch (ERRNO) { switch (ERRNO) {
case ERRSOC (EWOULDBLOCK): case ERRSOC(EWOULDBLOCK):
case ERRSOC (ECONNRESET): case ERRSOC(ECONNRESET):
case ERRSOC (ECONNABORTED): DBG_IO ("Client disconnected"); break; case ERRSOC(ECONNABORTED): DBG_IO("Client disconnected"); break;
default: DBG_IO ("Receiving error :" << ERRNO); default: DBG_IO("Receiving error: " << ERRNO);
} }
stop (); stop ();
} }
else { else {
inbuf << string (data, lgdata); inbuf << string (data, lgdata);
if (DEBUG_IO) { if (DEBUG_IO) {
string s (data, lgdata); string s (data, lgdata);
bool ok= true; bool ok= true;
for (int i=0; i<N(s); i++) for (int i= 0; i < N(s); i++)
if (((int) (unsigned char) s[i]) >= 128 || if (((int) (unsigned char) s[i]) >= 128 ||
(((int) (unsigned char) s[i]) < 32 && (((int) (unsigned char) s[i]) < 32 &&
s[i] != '\n' && s[i] != '\t')) ok= false; s[i] != '\n' && s[i] != '\t')) ok= false;
if (ok) { DBG_IO ("Data received:" << s); } if (ok) { DBG_IO("Data received: " << s); }
else { DBG_IO ("Binary data received size=" << N(s)); } else { DBG_IO("Binary data received size= " << N(s)); }
} }
qsnr->setEnabled (true); qsnr->setEnabled (true);
} }
} }
void void
socket_link::ready_to_send (int s) { socket_link::ready_to_send (int s) {
#ifdef OS_MINGW #ifdef OS_MINGW
using namespace wsoc; using namespace wsoc;
#endif #endif
qsnw->setEnabled (false); qsnw->setEnabled (false);
int sz= N (outbuf); int sz= N(outbuf);
if (sz) { if (sz) {
char *buf= as_charp (outbuf); char* buf= as_charp (outbuf);
int ret= WRITE (s, buf, sz); int ret= WRITE(s, buf, sz);
DBG_IO ("Socket outcoming code=" << ret); DBG_IO ("Socket outcoming code= " << ret);
if (ret >0) { if (ret >0) {
if (ret == sz) outbuf= ""; else outbuf= outbuf (ret,sz); if (ret == sz) outbuf= ""; else outbuf= outbuf (ret, sz);
sz -= ret; sz -= ret;
if (sz) qsnw->setEnabled (true); if (sz) qsnw->setEnabled (true);
} }
else if (ret <0) { else if (ret <0) {
DBG_IO ("Sending error:" << strerror(ERRNO)); DBG_IO ("Sending error: " << strerror (ERRNO));
stop (); stop ();
} }
else qsnw->setEnabled (true); else qsnw->setEnabled (true);
} }
} }
void void
socket_link::listen (int msecs) { socket_link::listen (int msecs) {
#ifdef OS_MINGW #ifdef OS_MINGW
using namespace wsoc; using namespace wsoc;
#endif #endif
if (!alive ()) return; if (!alive ()) return;
ready_to_send (sock); // do some writing if any pending ready_to_send (sock);
fd_set rfds; fd_set rfds;
FD_ZERO (&rfds); FD_ZERO (&rfds);
FD_SET (sock, &rfds); FD_SET (sock, &rfds);
struct timeval tv; struct timeval tv;
tv.tv_sec = msecs / 1000; tv.tv_sec = msecs / 1000;
tv.tv_usec = 1000 * (msecs % 1000); tv.tv_usec= 1000 * (msecs % 1000);
int nr= select (sock+1, &rfds, NULL, NULL, &tv); int nr= select (sock+1, &rfds, NULL, NULL, &tv);
if (nr ==1) data_set_ready (sock); //collect data if (nr == 1) data_set_ready (sock);
DBG_IO ("listen result :" << nr); DBG_IO ("Listenning result: " << nr);
if (nr == -1) stop(); if (nr == -1) stop();
} }
void void
socket_link::write (string s, int channel) { socket_link::write (string s, int channel) {
DBG_IO ("Socket write size=" << N(s)); DBG_IO ("Socket write size= " << N(s));
if ((!alive ()) || (channel != LINK_IN) || !N(s)) return; if ((!alive ()) || (channel != LINK_IN) || !N(s)) return;
outbuf << s; outbuf << s;
qsnw->setEnabled(true); qsnw->setEnabled(true);
} }
socket_server::socket_server (in_addr_t add, u_short port) { socket_server::socket_server (string host, unsigned short port) {
struct SOCKADDR_IN server; c_string _port (as_string (port));
c_string _host (host);
//Create socket struct ADDRINFO hints;
sock= NMSPC (socket (AF_INET , SOCK_STREAM , 0)); struct ADDRINFO *result, *rp;
if (sock == -1) { err= ERRNO; st= ST_SOCKET; return;} memset(&hints, 0, sizeof(struct ADDRINFO));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
hints.ai_protocol = 0;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
int x = GETADDRINFO (host == "" ? (char*) NULL : (char*)_host,
_port, &hints, &result);
if (x != 0) {
DBG_IO(GAI_STRERROR(x));
err= ERRNO;
st= ST_GETHOST;
return;
}
sock = -1;
for (rp = result; rp != NULL; rp = rp->ai_next) {
DBG_IO ("Serving at " *
string_from_socket_address ((SOCKADDR_STORAGE*) rp->ai_addr));
sock= SOCKET (rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sock < 0)
continue;
#ifndef OS_MINGW #ifndef OS_MINGW
if (fcntl (sock, F_SETFL, O_NONBLOCK) == -1) { if (fcntl (sock, F_SETFL, O_NONBLOCK) == -1)
err= ERRNO; st= ST_FCNTL; return; } continue;
#else #else
{ { using namespace wsoc;
unsigned long flags = -1; u_long flags = -1;
if (wsoc::ioctlsocket (sock, FIONBIO, &flags) == SOCKET_ERROR) { if (ioctlsocket (sock, FIONBIO, &flags) == SOCKET_ERROR)
err= ERRNO; st= ST_FCNTL; return; } continue;
} }
#endif #endif
if (BIND (sock, rp->ai_addr, rp->ai_addrlen) == 0)
//Prepare the sockaddr_in structure break;
server.sin_family= AF_INET; DBG_IO (strerror (errno));
server.sin_addr.s_addr= add; DBG_IO ("Socket bind failed");
server.sin_port= NMSPC(htons(port)); CLOSE (sock);
sock = -1;
if (NMSPC (bind (sock, (struct SOCKADDR *)&server, sizeof(server)))) { }
err=ERRNO; st=ST_BIND; return; } FREEADDRINFO (result);
if (NMSPC(listen (sock , 3))) { err= ERRNO; st= ST_LISTEN; return; } if (sock == -1) {
qsnc= new QSocketNotifier (sock, QSocketNotifier::Read); DBG_IO ("Cannot find socket binding for server");
err= ERRNO;
QObject::connect(qsnc, SIGNAL(activated(int)), this, SLOT(connection(int))); st= ST_BIND;
DBG_IO ("wait for connection"); return;
}
if (LISTEN (sock, 10) != 0) {
DBG_IO ("Cannot listen on server socket");
err= ERRNO;
st= ST_LISTEN;
return;
}
qsnc= tm_new<QSocketNotifier> (sock, QSocketNotifier::Read);
QObject::connect (qsnc, SIGNAL (activated(int)), this, SLOT (connection(int)))
;
DBG_IO ("Wait for connection");
} }
void void
socket_server::connection (int s) { socket_server::connection (int s) {
int sclt; socket_link *clt; int sclt; socket_link* clt;
struct SOCKADDR_IN cltadd; SOCKADDR_STORAGE cltadd;
socklen_t sz= sizeof (cltadd); socklen_t sz= sizeof (cltadd);
if (!qsnc->isEnabled ()) return; if (!qsnc->isEnabled ()) return;
//accept connection from an incoming client sclt= ACCEPT (s, (SOCKADDR*) &cltadd, &sz);
sclt= NMSPC (accept (s, (SOCKADDR*) &cltadd, &sz));
if (sclt > 0) { if (sclt > 0) {
clt= tm_new <socket_link> (sclt, &cltadd); clt= tm_new<socket_link> (sclt, &cltadd);
if (clt) { if (clt) {
if (clt->alive ()) { if (clt->alive ()) {
connect (clt, SIGNAL (disconnection(socket_link*)), this, connect (clt, SIGNAL (disconnection(socket_link*)), this,
SLOT (disconnection (socket_link*))); SLOT (disconnection (socket_link*)));
clts->insert ((pointer) clt); clts->insert ((pointer) clt);
call ("server-add", object (clt->getid ())); call ("server-add", object (clt->getid ()));
DBG_IO ("Client Connected " << show_addr (cltadd.sin_addr.s_addr) DBG_IO ("Client Connected from "
<< " id:" << clt->getid ()); << string_from_socket_address (&cltadd)
<< ", with id: " << clt->getid ());
} }
else tm_delete (clt); else tm_delete (clt);
} }
} }
else switch (ERRNO) { else switch (ERRNO) {
case ERRSOC (EWOULDBLOCK): case ERRSOC (EWOULDBLOCK):
case ERRSOC (ECONNABORTED): break; case ERRSOC (ECONNABORTED): break;
default: err=ERRNO; qsnc->setEnabled (false); st=ST_CONNECTION; default: err= ERRNO; qsnc->setEnabled (false); st= ST_CONNECTION;
} }
} }
void void
socket_server::disconnection(socket_link* clt) { socket_server::disconnection (class socket_link* clt) {
call ("server-remove", object (clt->getid())); call ("server-remove", object (clt->getid()));
clts->remove((pointer) clt); clts->remove ((pointer) clt);
tm_delete(clt); tm_delete (clt);
} }
string string
socket_server::read (IdClt id) { socket_server::read (int id) {
class socket_link *clt= find_client (id); socket_link *clt= find_client (id);
if (!clt) return ""; if (!clt) return "";
bool success; bool success;
string back= clt->read_packet (LINK_OUT, 0, success); string back= clt->read_packet (LINK_OUT, 0, success);
return back; return back;
} }
void void
socket_server::write (IdClt id, string s) { socket_server::write (int id, string s) {
class socket_link *clt= find_client (id); socket_link *clt= find_client (id);
if (clt) clt->write_packet(s, LINK_IN); if (clt) clt->write_packet(s, LINK_IN);
} }
class socket_link * socket_link *
socket_server::find_client(IdClt id) { socket_server::find_client (int id) {
iterator<pointer> it= iterate (clts); iterator<pointer> it= iterate (clts);
while (it->busy ()) { while (it->busy ()) {
socket_link* clt= (socket_link*) it->next (); socket_link* clt= (socket_link*) it->next ();
if (clt->getid() == id) return clt; if (clt->getid() == id) return clt;
} }
array<IdClt> ids; array<int> ids;
it= iterate (clts); it= iterate (clts);
while (it->busy ()) { while (it->busy ()) {
socket_link* clt= (socket_link*) it->next (); socket_link* clt= (socket_link*) it->next ();
ids << clt->getid(); ids << clt->getid();
} }
DBG_IO ("Client not found, Id = " << id << ", Among = " << ids); DBG_IO ("Client not found, id= " << id << ", among= " << ids);
return NULL; return NULL;
} }
socket_server::~socket_server() { socket_server::~socket_server () {
iterator<pointer> it= iterate (clts); iterator<pointer> it= iterate (clts);
while (it->busy ()) { while (it->busy ()) {
socket_link* clt= (socket_link*) it->next (); socket_link* clt= (socket_link*) it->next ();
disconnection (clt); disconnection (clt);
} }
} }
string string
debug_io_string (string s) { debug_io_string (string s) {
int i, n= N(s); int i, n= N(s);
 End of changes. 56 change blocks. 
152 lines changed or deleted 190 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)