Winsock TCP

15 篇文章 0 订阅
//#############################################  


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值