//############################################# #include "stdafx.h" #include <winsock.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include "tcp.h" int wsa_ok =0; void peek_message(void); int get_local_ip(char *ip); #define WM_TCP WM_APP+100 //extern int sd_connect, sd_bind, sd_accept; int tcp_init(); int tcp_exit(); int tcp_status(int sd, char *type, int timeout); int tcp_bind(HWND hWnd, int port); int tcp_accept(int sd, int timeout); int tcp_connect(char *hostname, int port, int timeout, int f_noblock); void tcp_disconnect(int sd); void tcp_close(int sd); int tcp_send(int sd, char *buf, int len, int timeout); int tcp_recv(int sd, char *buf, int len, int timeout); int tcp_gethostnamebyip(char *ip, char *name); unsigned short tcp_htons(unsigned short); unsigned short tcp_ntohs(unsigned short); unsigned long int tcp_htonl(unsigned long int); unsigned long int tcp_ntohl(unsigned long int); float tcp_htonf(float f); float tcp_ntohf(float f); double tcp_htond(double d); double tcp_ntohd(double d); char *get_remote_ip(int sd, char *ip); int tcp_init() { WSAData wsa; //sd_bind =sd_connect =sd_accept =-1; if(WSAStartup(MAKEWORD(1, 1), &wsa) !=0) return -1; wsa_ok =1; return 0; } int tcp_exit() { if(wsa_ok) WSACleanup(); return 0; } int tcp_status(int sd, char *type, int timeout) { fd_set rset, wset, eset; fd_set FAR *prset =NULL, *pwset =NULL, *peset =NULL; struct timeval tval; int i, status, err_no =0; time_t t1, t2; MSG msg; tval.tv_sec =0; tval.tv_usec =0; time(&t1); t2 =t1; while(t2-t1 < timeout) { FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&eset); for(i =0; i<(int)strlen(type); i++) { if(type[i] =='r') { FD_SET(sd, &rset); prset =&rset; } if(type[i] =='w') { FD_SET(sd, &wset); pwset =&wset; } if(type[i] =='e') { FD_SET(sd, &eset); peset =&eset; } } status =select(-1/*sd+1*/, prset, pwset, peset, &tval); time(&t2); if(status ==0) { if(PeekMessage(&msg, 0, NULL, NULL, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); if(msg.message ==WM_QUIT) return -1; } if(t2-t1 <timeout) continue; else { if(prset) FD_CLR((UINT)sd,&rset); if(pwset) FD_CLR((UINT)sd,&wset); if(peset) FD_CLR((UINT)sd,&eset); SetLastError(WSAETIMEDOUT); return -10; } }if(peset && FD_ISSET(sd, peset)) { if(prset !=NULL) FD_CLR((UINT)sd,&rset); if(pwset !=NULL) FD_CLR((UINT)sd,&wset); if(peset !=NULL) FD_CLR((UINT)sd,&eset); err_no =WSAGetLastError(); /* len =sizeof(errno); getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&errno, &len); */ return -1; } if((prset && FD_ISSET(sd, prset)) || (pwset && FD_ISSET(sd, pwset))) { err_no =WSAGetLastError(); /* len =sizeof(errno); getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&errno, &len); */ } if(prset !=NULL) FD_CLR((UINT)sd,&rset); if(pwset !=NULL) FD_CLR((UINT)sd,&wset); if(peset !=NULL) FD_CLR((UINT)sd,&eset); if(status <0) err_no =WSAGetLastError(); if(err_no ==WSAEINTR) return WSAEINTR; if(err_no) { return -1; } else break; } return 0; int tcp_bind(HWND hWnd, int port) { struct sockaddr_in addr; char temp[200]; int sd; sd =-1; if((sd =socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <0) { sprintf(temp, "socket failed! errno:%d", WSAGetLastError()); return -1; } memset(&addr, 0, sizeof(addr)); addr.sin_family =AF_INET; addr.sin_port =htons((unsigned short)port); int l =1; setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&l, sizeof(l)); /*setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, (char *)&l, sizeof(l));*/ if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) <0) { sprintf(temp, "bind failed! errno:%d", WSAGetLastError()); closesocket(sd); return -1; } if(hWnd && WSAAsyncSelect(sd, hWnd, WM_TCP, FD_ACCEPT) !=0) { sprintf(temp, "tcp_bind:WSAAsyncSelect failed!"); closesocket(sd); return -2; } //sd_bind =sd; listen(sd, 5); return sd; } int tcp_accept(int sd, int timeout) { int sd_acc =-1; struct sockaddr_in sa; int len; /*unsigned long l;*/ if(tcp_status(sd, "rw", timeout) <0) return -1; len =sizeof(sa); if((sd_acc =accept(sd, (struct sockaddr *)&sa, &len)) <0) return -1; //sd_accept =sd_acc; /* l =1; if(ioctlsocket(sd_acc, FIONBIO, &l) <0) { closesocket(sd); return -1; }*/ return sd_acc; } int tcp_connect(char *hostname, int port, int timeout, int f_noblock) { struct hostent *hp; struct sockaddr_in addr; char temp[200]; unsigned long ul; long l; int sd =-1, ret; time_t t1, t2; sd =-1; if((sd =socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <0) { sprintf(temp, "socket failed! errno:%d", WSAGetLastError()); return -1; } memset(&addr, 0, sizeof(addr)); ul =inet_addr(hostname); if(ul ==0xffffffff) { if((hp =gethostbyname(hostname)) ==NULL) { sprintf(temp, "gethostbyname and inet_addr failed! errno:%d", WSAGetLastError()); closesocket(sd); return -1; } memcpy(&addr.sin_addr, hp->h_addr, hp->h_length); } else addr.sin_addr.s_addr=ul; addr.sin_family =AF_INET; addr.sin_port =htons((unsigned short)port); l =1; if(/*f_noblock && */ioctlsocket(sd, FIONBIO, (unsigned long *)&l) <0) { closesocket(sd); return -1; } /*if(setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (char *)&l, sizeof(l)) <0) { closesocket(sd); return -1; }*/ time(&t1); while((ret =connect(sd, (struct sockaddr *)&addr, sizeof(addr))) !=0) { time(&t2); if((t2 -t1) > timeout) { closesocket(sd); return -1; } peek_message(); int err_no =WSAGetLastError(); if(ret ==SOCKET_ERROR) { if(err_no ==WSAEISCONN) break; } else if(err_no ==WSAEWOULDBLOCK /*|| err_no ==WSAEINPROGRESS*/ || err_no ==WSAEALREADY) { continue; } else { closesocket(sd); return -1; } } if(tcp_status(sd, "we", timeout) <0) { sprintf(temp, "status:连接服务器失败!\n检查服务器端程序是否运行\n且主机地址是否%s, 端口是否%d\n" "errno=%d", hostname, port, WSAGetLastError()); closesocket(sd); return -1; } //sd_connect =sd; return sd; } void tcp_close(int sd) { tcp_disconnect(sd); } void tcp_disconnect(int sd) { if(sd >0) { closesocket(sd); //if(sd ==sd_connect) sd_connect =-1; //if(sd ==sd_accept) sd_accept =-1; //if(sd ==sd_bind) sd_bind =-1; } } int tcp_send(int sd, char *buf, int len, int timeout) { int len1, len_send =0; time_t t1, t2; len_send =0; time(&t1); t2 =t1; while(len_send <len) { if(t2-t1 >timeout) return len_send; if(tcp_status(sd, "w", timeout-(t2-t1)) <0) return len_send; if((len1 =send(sd, &buf[len_send], len-len_send, 0)) <=0) { if(len1 ==SOCKET_ERROR && GetLastError() ==WSAEWOULDBLOCK) { time(&t2); continue; } return len_send; } len_send +=len1; time(&t2); } return len_send; }int tcp_recv(int sd, char *buf, int len, int timeout) { int len1, len_recv; time_t t2, t1; len_recv =0; time(&t1); t2 =t1; while(len_recv <len) { if(t2 -t1 >timeout) return len_recv; if(tcp_status(sd, "r", timeout-(t2-t1)) <0) return len_recv; if((len1 =recv(sd, &buf[len_recv], len-len_recv, 0)) <=0) { if(timeout ==0) break; if(len1 ==SOCKET_ERROR && GetLastError() ==WSAEWOULDBLOCK) { time(&t2); continue; } return len_recv; } len_recv +=len1; time(&t2); } return len_recv; } int tcp_gethostnamebyip(char *ip, char *host) { struct hostent *hp; struct in_addr ul; host[0] =0; ul.S_un.S_addr =inet_addr(ip); if(ul.S_un.S_addr ==0xFFFFFFFF) return -1; // ip error or ip is hostname hp =gethostbyaddr((char *)&ul, 4, AF_INET); if(hp ==NULL) return -1; // can not get hostname strcpy(host, hp->h_name); return 0; } int get_local_ip(char *ip) { struct hostent *hp; char host[50], *p; if(gethostname(host, sizeof(host)) <0) return -1; hp =gethostbyname(host); if(hp ==NULL) return -1; p =(char *)hp->h_addr; wsprintf(ip, "%d.%d.%d.%d", (int)p[0]&0xFF, (int)p[1]&0xFF, (int)p[2]&0xFF, (int)p[3]&0xFF); return 0; } char *get_remote_ip(int sd, char *ip) { struct sockaddr_in addr_in; int len =sizeof(addr_in); char *p1; if(sd <0) return NULL; if(getpeername(sd, (struct sockaddr *)&addr_in, &len) <0) return NULL; p1 =(char *)&addr_in.sin_addr; sprintf(ip, "%d.%d.%d.%d", ((int)p1[0]) &0xff, ((int)p1[1]) &0xff, (int)p1[2] &0xff, (int)p1[3]&0xff); return ip; } unsigned short tcp_htons(unsigned short s) { return htons(s); } unsigned short tcp_ntohs(unsigned short s) { return ntohs(s); } unsigned long int tcp_htonl(unsigned long int l) { return htonl(l); } unsigned long int tcp_ntohl(unsigned long int l) { return ntohl(l); } float tcp_htonf(float f) { unsigned char *p, p0, p1; if(htons(1) ==1) return f; p =(unsigned char *)&f; p0 =p[0]; p1 =p[1]; p[0] =p[3]; p[3] =p0; p[1] =p[2]; p[2] =p1; return f; }float tcp_ntohf(float f) { unsigned char *p, p0, p1; if(ntohs(1) ==1) return f; p =(unsigned char *)&f; p0 =p[0]; p1 =p[1]; p[0] =p[3]; p[3] =p0; p[1] =p[2]; p[2] =p1; return f; } double tcp_htond(double d) { unsigned char *p, p0, p1, p2, p3; if(htons(1) ==1) return d; p =(unsigned char *)&d; p0 =p[0]; p1 =p[1]; p2 =p[2]; p3 =p[3]; p[0] =p[7]; p[7] =p0; p[1] =p[6]; p[6] =p1; p[2] =p[5]; p[5] =p2; p[3] =p[4]; p[4] =p3; return d; } double tcp_ntohd(double d) { unsigned char *p, p0, p1, p2, p3; if(ntohs(1) ==1) return d; p =(unsigned char *)&d; p0 =p[0]; p1 =p[1]; p2 =p[2]; p3 =p[3]; p[0] =p[7]; p[7] =p0; p[1] =p[6]; p[6] =p1; p[2] =p[5]; p[5] =p2; p[3] =p[4]; p[4] =p3; return d; } void peek_message(void) { MSG msg; if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } }