SOCKET skt_connect(skt_ip_t ip, int port, int timeout) { struct sockaddr_in addr=skt_build_addr(ip,port); int ok, begin; SOCKET ret; begin = time(0); while (time(0)-begin < timeout) { ret = socket(AF_INET, SOCK_STREAM, 0); if (ret==SOCKET_ERROR) { if (skt_should_retry()) continue; else return skt_abort(-1, 93512, "Error creating socket"); } ok = connect(ret, (struct sockaddr *)&(addr), sizeof(addr)); if (ok != SOCKET_ERROR) return ret;/*Good connect*/ else { /*Bad connect*/ skt_close(ret); if (skt_should_retry()) continue; else { #if ! defined(_WIN32) || defined(__CYGWIN__) if (ERRNO == ETIMEDOUT) continue; /* time out is fine */ #endif return skt_abort(-1, 93515, "Error connecting to socket\n"); } } } /*Timeout*/ if (timeout==60) return skt_abort(-1, 93517, "Timeout in socket connect\n"); return INVALID_SOCKET; }
SOCKET skt_connect(skt_ip_t ip, int port, int timeout) { struct sockaddr_in addr=skt_build_addr(ip,port); int ok, begin; SOCKET ret; begin = time(0); while (time(0)-begin < timeout) { ret = socket(AF_INET, SOCK_STREAM, 0); if (ret==SOCKET_ERROR) { if (skt_should_retry()) continue; else return skt_abort(93512,"Error creating socket"); } ok = connect(ret, (struct sockaddr *)&(addr), sizeof(addr)); if (ok != SOCKET_ERROR) return ret;/*Good connect*/ else { /*Bad connect*/ skt_close(ret); if (skt_should_retry()) continue; else return skt_abort(93515,"Error connecting to socket\n"); } } /*Timeout*/ return skt_abort(93517,"Timeout in socket connect\n"); }
int skt_sendN(SOCKET hSocket,const void *buff,int nBytes) { int nLeft,nWritten; const char *pBuff=(const char *)buff; nLeft = nBytes; while (0 < nLeft) { skt_ignore_SIGPIPE=1; nWritten = send(hSocket,pBuff,nLeft,0); skt_ignore_SIGPIPE=0; if (nWritten<=0) { if (nWritten==0) return skt_abort(93720,"Socket closed before send."); if (skt_should_retry()) continue;/*Try again*/ else return skt_abort(93700+hSocket,"Error on socket send!"); } else { nLeft -= nWritten; pBuff += nWritten; } } return 0; }
int skt_recvN(SOCKET hSocket,void *buff,int nBytes) { int nLeft,nRead; char *pBuff=(char *)buff; nLeft = nBytes; while (0 < nLeft) { if (0==skt_select1(hSocket,60*1000)) return skt_abort(93610,"Timeout on socket recv!"); skt_ignore_SIGPIPE=1; nRead = recv(hSocket,pBuff,nLeft,0); skt_ignore_SIGPIPE=0; if (nRead<=0) { if (nRead==0) return skt_abort(93620,"Socket closed before recv."); if (skt_should_retry()) continue;/*Try again*/ else return skt_abort(93650+hSocket,"Error on socket recv!"); } else { nLeft -= nRead; pBuff += nRead; } } return 0; }
SOCKET skt_server_ip(unsigned int *port,skt_ip_t *ip) { SOCKET ret; socklen_t len; int on = 1; /* for setsockopt */ int connPort=(port==NULL)?0:*port; struct sockaddr_in addr=skt_build_addr((ip==NULL)?_skt_invalid_ip:*ip,connPort); retry: ret = socket(PF_INET, SOCK_STREAM, 0); if (ret == SOCKET_ERROR) { if (skt_should_retry()) goto retry; else return skt_abort(93483,"Error creating server socket."); } /* Prevents 3-minute socket reuse timeout after a server crash. */ setsockopt(ret, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on)); if (bind(ret, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) return skt_abort(93484,"Error binding server socket. Is another process listening on that port already?"); if (listen(ret,5) == SOCKET_ERROR) return skt_abort(93485,"Error listening on server socket."); len = sizeof(addr); if (getsockname(ret, (struct sockaddr *)&addr, &len) == SOCKET_ERROR) return skt_abort(93486,"Error getting name on server socket."); if (port!=NULL) *port = (int)ntohs(addr.sin_port); if (ip!=NULL) memcpy(ip, &addr.sin_addr, sizeof(*ip)); return ret; }
SOCKET skt_datagram(unsigned int *port, int bufsize) { int connPort=(port==NULL)?0:*port; struct sockaddr_in addr=skt_build_addr(_skt_invalid_ip,connPort); socklen_t len; SOCKET ret; retry: ret = socket(AF_INET,SOCK_DGRAM,0); if (ret == SOCKET_ERROR) { if (skt_should_retry()) goto retry; return skt_abort(93490,"Error creating datagram socket."); } if (bind(ret, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) return skt_abort(93491,"Error binding datagram socket."); len = sizeof(addr); if (getsockname(ret, (struct sockaddr *)&addr , &len)) return skt_abort(93492,"Error getting address on datagram socket."); if (bufsize) { len = sizeof(int); if (setsockopt(ret, SOL_SOCKET , SO_RCVBUF , (char *)&bufsize, len) == SOCKET_ERROR) return skt_abort(93495,"Error on RCVBUF sockopt for datagram socket."); if (setsockopt(ret, SOL_SOCKET , SO_SNDBUF , (char *)&bufsize, len) == SOCKET_ERROR) return skt_abort(93496,"Error on SNDBUF sockopt for datagram socket."); } if (port!=NULL) *port = (int)ntohs(addr.sin_port); return ret; }
/*Sleep on given read socket until msec or readable*/ int skt_select1(SOCKET fd,int msec) { int sec=msec/1000; fd_set rfds; struct timeval tmo, *tmp=&tmo; int secLeft=sec; int begin=0, nreadable; if (!skt_inited) skt_init(); FD_ZERO(&rfds); FD_SET(fd, &rfds); if (msec>0) begin = time(0); else /* msec zero-- disable timeout */ tmp=NULL; do { tmo.tv_sec=secLeft; tmo.tv_usec = (msec-1000*sec)*1000; skt_ignore_SIGPIPE=1; nreadable = select(1+fd, &rfds, NULL, NULL, tmp); skt_ignore_SIGPIPE=0; if (nreadable < 0) { if (skt_should_retry()) continue; else return skt_abort(93200,"Fatal error in select"); } if (nreadable >0) return 1; /*We gotta good socket*/ } while(msec>0 && ((secLeft = sec - (time(0) - begin))>0)); return 0;/*Timed out*/ }
int skt_select1(SOCKET fd,int msec) { struct pollfd fds[1]; int begin, nreadable; int sec=msec/1000; int secLeft=sec; fds[0].fd=fd; fds[0].events=POLLIN; if (msec>0) begin = time(0); do { skt_ignore_SIGPIPE=1; nreadable = poll(fds, 1, msec); skt_ignore_SIGPIPE=0; if (nreadable < 0) { if (skt_should_retry()) continue; else skt_abort(fd, 93200, "Fatal error in poll"); } if (nreadable >0) return 1; /*We gotta good socket*/ } while(msec>0 && ((secLeft = sec - (time(0) - begin))>0)); return 0;/*Timed out*/ }
SOCKET skt_accept(SOCKET src_fd,skt_ip_t *pip, unsigned int *port) { socklen_t len; struct sockaddr_in addr={0}; SOCKET ret; len = sizeof(addr); retry: ret = accept(src_fd, (struct sockaddr *)&addr, &len); if (ret == SOCKET_ERROR) { if (skt_should_retry()) goto retry; else return skt_abort(93523,"Error in accept."); } if (port!=NULL) *port=ntohs(addr.sin_port); if (pip!=NULL) memcpy(pip,&addr.sin_addr,sizeof(*pip)); return ret; }