www.pudn.com > tcp.zip > tcp.cpp, change:2000-07-11,size:10002b


#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); 
 
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); 
  } 
}