套接字网络编程笔记


1.调用int send( __in  SOCKET s, __in  const char* buf, __in  int len, __in  int flags); 发出的数据包,在传送过程中,虽然顺序不会把打乱,但可能会拆分成多个包,这样,只调用一次int recv( __in   SOCKET s, __out  char* buf, __in   int len, __in   int flags); 可能不能被完整地接收。

解决的方法是,定义TCP之上的协议,即应用层协议,指示数据包长度。最简单的实现为:

  1. void SendFn(SOCKET s, char* data, int len)  
  2. {  
  3.     char* buff = (char*)malloc(sizeof(int)+len);  
  4.   
  5.     //填充报文头   
  6.     int* pLen = (int*)buff;  
  7.     *pLen = len;  
  8.   
  9.     //填充有效数据   
  10.     memcpy(buff+sizeof(int), data, len);  
  11.   
  12.     send(s, buff, sizeof(int)+len, 0);  
  13. }  
  14.   
  15. //完整接收指定长度数据包   
  16. void RecvFnS(SOCKET s, char* buff, int len)  
  17. {  
  18.     int done = 0;  
  19.     done = recv(s, buff, len, 0);  
  20.   
  21.     while ( done < len )  
  22.         done += recv(s, buff+done, len, 0);  
  23. }  
  24.   
  25. void RecvFn(SOCKET s)  
  26. {  
  27.     int len;  
  28.     //接收报文头   
  29.     RecvFnS(s, (char*)&len, sizeof(int));  
  30.   
  31.     //接收有效数据   
  32.     if ( len > 0 )  
  33.     {     
  34.         char* buff = (char*)malloc(len);  
  35.         RecvFnS(s, buff, len);  
  36.     }  
  37. }  

2.TCP通信时,服务器用SOCKET accept( __in     SOCKET s, __out    struct sockaddr* addr, __inout  int* addrlen); 创建的套接字共同占用一个端口,即服务器监听端口。

为什么要这么做:客服端套接字指定通信对方的端口就是监听端口,没有理由找一个使用其它端口的套接字跟它连接。

为什么能这么做:TCP报文中,包含源端口,与目标端口,再加上IP层的源IP地址及目标IP地址,这四个信息,就是运输层多路分解中,所需要的四元组,意思是可以唯一确定一个TCP连接。当从IP层,解包数据后,就可以根据四元组,找到这些数据的目标TCP连接。这点跟UDP连接是有区别的,因为UDP多路分解时只使用目标IP地址及目标端口,所以,只要目标IP为本机IP,目标端口为监听端口的,UDP连接都会定向到一个UPD连接。这意味,UDP是一个一对多的连接(确切地说UPD不能叫连接)。

  • 1
  • 2
  • 下一页

相关内容