套接字选项—修改套接字缓冲区大小

http://blog.csdn.net/wangningyu/article/details/4568514

有时候我们需要控制套接字的行为(如修改缓冲区的大小),这个时候我们就要学习套接字选项。

 

[cpp] view plain copy print ?
  1. int getsockopt(int sockfd,int level,int optname,void *optval,socklen_t *optlen)  
  2. int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t *optlen)  
int getsockopt(int sockfd,int level,int optname,void *optval,socklen_t *optlen) int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t *optlen)

 

level指定控制套接字的层次.可以取三种值:

1)SOL_SOCKET:通用套接字选项. 

2)IPPROTO_IP:IP选项. 

3)IPPROTO_TCP:TCP选项. 


optname指定控制的方式(选项的名称),我们下面详细解释 

optval获得或者是设置套接字选项.根据选项名称的数据类型进行转换
 


选项名称                说明                                    数据类型
========================================================================
                        SOL_SOCKET
------------------------------------------------------------------------
SO_BROADCAST        允许发送广播数据                    int
SO_DEBUG                允许调试                                int
SO_DONTROUTE        不查找路由                             int
SO_ERROR                 获得套接字错误                       int
SO_KEEPALIVE          保持连接                                 int
SO_LINGER               延迟关闭连接                           struct linger
SO_OOBINLINE         带外数据放入正常数据流            int
SO_RCVBUF               接收缓冲区大小                        int
SO_SNDBUF               发送缓冲区大小                        int
SO_RCVLOWAT          接收缓冲区下限                        int
SO_SNDLOWAT          发送缓冲区下限                        int
SO_RCVTIMEO           接收超时                                 struct timeval
SO_SNDTIMEO           发送超时                                 struct timeval
SO_REUSERADDR       允许重用本地地址和端口            int
SO_TYPE                    获得套接字类型                         int
SO_BSDCOMPAT        与BSD系统兼容                         int
==========================================================================
                        IPPROTO_IP
--------------------------------------------------------------------------
IP_HDRINCL              在数据包中包含IP首部                    int
IP_OPTINOS              IP首部选项                                   int
IP_TOS                      服务类型
IP_TTL                       生存时间                                      int
==========================================================================
                        IPPRO_TCP
--------------------------------------------------------------------------
TCP_MAXSEG              TCP最大数据段的大小                     int
TCP_NODELAY            不使用Nagle算法                           int
=========================================================================

 

大致介绍这么多,还是看源码吧:

[cpp] view plain copy print ?
  1. //////////////////////////////////////////////////////////////////////////   
  2. // SocketOptionSrv.cpp   
  3. // 套接字选项 —— 设置缓冲大小(扩大10倍)   
  4.   
  5. #include <iostream.h>   
  6. #include <winsock2.H>   
  7.   
  8. #define BUF_SIZE    64   
  9. #pragma comment(lib,"ws2_32.lib")   
  10.   
  11. int main(int argc,char* argv[])  
  12. {  
  13.     WSADATA         wsd;  
  14.     SOCKET          s;  
  15.     SOCKADDR_IN     servAddr;  
  16.     char            bufRecv[BUF_SIZE];  
  17.     char            bufSend[BUF_SIZE];  
  18.   
  19.     // 初始化套接字   
  20.     if(WSAStartup(MAKEWORD(2,2),&wsd))  
  21.     {  
  22.         cout<<"WSAStartup failed !/n"<<endl;  
  23.         return 1;  
  24.     }  
  25.     // 连理套接字   
  26.     s = socket(AF_INET,SOCK_DGRAM,0);  
  27.     if(INVALID_SOCKET == s)  
  28.     {  
  29.         cout<<"socket failed !/n"<<endl;  
  30.         WSACleanup();  
  31.         return 1;  
  32.     }  
  33.   
  34.     int nErrorCode;  
  35.     int nBufLen;  
  36.     int nOptLen = sizeof(nBufLen);  
  37.   
  38.     // 获取当前套接字s的接受数据缓冲区大小   
  39.     nErrorCode = getsockopt(s,SOL_SOCKET,SO_RCVBUF,(char*)&nBufLen,&nOptLen);  
  40.     if(SOCKET_ERROR == nErrorCode)  
  41.     {  
  42.         cout<<"getsockopt failed !/n"<<endl;  
  43.         WSACleanup();  
  44.         return 1;  
  45.     }  
  46.   
  47.     // 设置当前套接字s的接受数据缓冲区为原来的10倍   
  48.     nBufLen *= 10;  
  49.     nErrorCode = setsockopt(s,SOL_SOCKET,SO_RCVBUF,(char*)&nBufLen,nOptLen);  
  50.     if(SOCKET_ERROR == nErrorCode)  
  51.     {  
  52.         cout<<"setsockopt failed !/n"<<endl;  
  53.         WSACleanup();  
  54.         return 1;  
  55.     }  
  56.   
  57.     // 检查套接字s的接受缓冲区是否设置成功   
  58.     int uiNewRcvBuf;  
  59.     getsockopt(s,SOL_SOCKET,SO_RCVBUF,(char*)&uiNewRcvBuf,&nOptLen);  
  60.     if(SOCKET_ERROR == nErrorCode || uiNewRcvBuf != nBufLen)  
  61.     {  
  62.         cout<<"The buf isn't same from Recv."<<endl;  
  63.         WSACleanup();  
  64.         return 1;  
  65.     }  
  66.   
  67.     // 设置服务器现象   
  68.     servAddr.sin_family = AF_INET;  
  69.     servAddr.sin_port = htons(5000);  
  70.     servAddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  71.   
  72.     // 绑定套接字   
  73.     if(bind(s,(SOCKADDR *)&servAddr,sizeof(SOCKADDR)) == SOCKET_ERROR)  
  74.     {  
  75.         cout<<"bind failed:"<<WSAGetLastError()<<endl;  
  76.         closesocket(s);  
  77.         WSACleanup();  
  78.         return 1;  
  79.     }  
  80.   
  81.     SOCKADDR_IN clientAddr;  
  82.     int         nClientLen;  
  83.   
  84.     // 缓冲区待发送的数据   
  85.     ZeroMemory(bufRecv,BUF_SIZE);  
  86.     ZeroMemory(bufSend,BUF_SIZE);  
  87.     strcpy(bufSend,"Hello World !");  
  88.     nClientLen = sizeof(clientAddr);  
  89.     while(1)  
  90.     {  
  91.         // 从客户端接受数据   
  92.         if(recvfrom(s,bufRecv,BUF_SIZE,0,(SOCKADDR *)&clientAddr,&nClientLen) == SOCKET_ERROR)  
  93.         {  
  94.             cout<<"recv failed:"<<WSAGetLastError()<<endl;  
  95.             closesocket(s);  
  96.             WSACleanup();  
  97.             return 1;  
  98.         }  
  99.         cout<<"Recv From Client:"<<bufRecv<<endl;  
  100.   
  101.         // 向服务器发送数据   
  102.         if(sendto(s,bufSend,BUF_SIZE,0,(SOCKADDR *)&clientAddr,nClientLen) == SOCKET_ERROR)  
  103.         {  
  104.             cout<<"send to Client failed:"<<WSAGetLastError()<<endl;  
  105.             closesocket(s);  
  106.             WSACleanup();  
  107.             return 1;  
  108.         }  
  109.     }  
  110.   
  111.     // 关闭套接字,释放资源   
  112.     closesocket(s);  
  113.     WSACleanup();  
  114.     return 0;  
  115. }  
////////////////////////////////////////////////////////////////////////// // SocketOptionSrv.cpp // 套接字选项 —— 设置缓冲大小(扩大10倍) #include <iostream.h> #include <winsock2.H> #define BUF_SIZE 64 #pragma comment(lib,"ws2_32.lib") int main(int argc,char* argv[]) { WSADATA wsd; SOCKET s; SOCKADDR_IN servAddr; char bufRecv[BUF_SIZE]; char bufSend[BUF_SIZE]; // 初始化套接字 if(WSAStartup(MAKEWORD(2,2),&wsd)) { cout<<"WSAStartup failed !/n"<<endl; return 1; } // 连理套接字 s = socket(AF_INET,SOCK_DGRAM,0); if(INVALID_SOCKET == s) { cout<<"socket failed !/n"<<endl; WSACleanup(); return 1; } int nErrorCode; int nBufLen; int nOptLen = sizeof(nBufLen); // 获取当前套接字s的接受数据缓冲区大小 nErrorCode = getsockopt(s,SOL_SOCKET,SO_RCVBUF,(char*)&nBufLen,&nOptLen); if(SOCKET_ERROR == nErrorCode) { cout<<"getsockopt failed !/n"<<endl; WSACleanup(); return 1; } // 设置当前套接字s的接受数据缓冲区为原来的10倍 nBufLen *= 10; nErrorCode = setsockopt(s,SOL_SOCKET,SO_RCVBUF,(char*)&nBufLen,nOptLen); if(SOCKET_ERROR == nErrorCode) { cout<<"setsockopt failed !/n"<<endl; WSACleanup(); return 1; } // 检查套接字s的接受缓冲区是否设置成功 int uiNewRcvBuf; getsockopt(s,SOL_SOCKET,SO_RCVBUF,(char*)&uiNewRcvBuf,&nOptLen); if(SOCKET_ERROR == nErrorCode || uiNewRcvBuf != nBufLen) { cout<<"The buf isn't same from Recv."<<endl; WSACleanup(); return 1; } // 设置服务器现象 servAddr.sin_family = AF_INET; servAddr.sin_port = htons(5000); servAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 绑定套接字 if(bind(s,(SOCKADDR *)&servAddr,sizeof(SOCKADDR)) == SOCKET_ERROR) { cout<<"bind failed:"<<WSAGetLastError()<<endl; closesocket(s); WSACleanup(); return 1; } SOCKADDR_IN clientAddr; int nClientLen; // 缓冲区待发送的数据 ZeroMemory(bufRecv,BUF_SIZE); ZeroMemory(bufSend,BUF_SIZE); strcpy(bufSend,"Hello World !"); nClientLen = sizeof(clientAddr); while(1) { // 从客户端接受数据 if(recvfrom(s,bufRecv,BUF_SIZE,0,(SOCKADDR *)&clientAddr,&nClientLen) == SOCKET_ERROR) { cout<<"recv failed:"<<WSAGetLastError()<<endl; closesocket(s); WSACleanup(); return 1; } cout<<"Recv From Client:"<<bufRecv<<endl; // 向服务器发送数据 if(sendto(s,bufSend,BUF_SIZE,0,(SOCKADDR *)&clientAddr,nClientLen) == SOCKET_ERROR) { cout<<"send to Client failed:"<<WSAGetLastError()<<endl; closesocket(s); WSACleanup(); return 1; } } // 关闭套接字,释放资源 closesocket(s); WSACleanup(); return 0; }

 

[cpp] view plain copy print ?
  1. //////////////////////////////////////////////////////////////////////////   
  2. // SocketOptionClient.cpp   
  3. // 套接字选项 —— 设置缓冲大小(扩大10倍)   
  4.   
  5. #include <iostream.h>   
  6. #include <winsock2.H>   
  7.   
  8. #define BUF_SIZE    64   
  9. #pragma comment(lib,"ws2_32.lib")   
  10.   
  11. int main(int argc,char* argv[])  
  12. {  
  13.     WSADATA         wsd;  
  14.     SOCKET          s;  
  15.     SOCKADDR_IN     servAddr;  
  16.     char            bufRecv[BUF_SIZE];  
  17.     char            bufSend[BUF_SIZE];  
  18.       
  19.     // 初始化套接字   
  20.     if(WSAStartup(MAKEWORD(2,2),&wsd))  
  21.     {  
  22.         cout<<"WSAStartup failed !/n"<<endl;  
  23.         return 1;  
  24.     }  
  25.   
  26.     // 建立套接字   
  27.     s = socket(AF_INET,SOCK_DGRAM,0);  
  28.     if(INVALID_SOCKET == s)  
  29.     {  
  30.         cout<<"socket failed !/n"<<endl;  
  31.         WSACleanup();  
  32.         return 1;  
  33.     }  
  34.   
  35.     // 缓冲区待发送的数据   
  36.     ZeroMemory(bufSend,BUF_SIZE);  
  37.     ZeroMemory(bufRecv,BUF_SIZE);  
  38.     strcpy(bufSend,"Hello World !");  
  39.   
  40.     // 设置服务器选项   
  41.     servAddr.sin_family = AF_INET;  
  42.     servAddr.sin_addr.s_addr = inet_addr("192.168.1.254");  
  43.     servAddr.sin_port = htons(5000);  
  44.   
  45.     int nServerlen = sizeof(servAddr);  
  46.     while(1)  
  47.     {  
  48.         // 向服务器发送数据   
  49.         if(sendto(s,bufSend,BUF_SIZE,0,(SOCKADDR *)&servAddr,nServerlen) == SOCKET_ERROR)  
  50.         {  
  51.             cout<<"sendto failed:"<<WSAGetLastError()<<endl;  
  52.             closesocket(s);  
  53.             WSACleanup();  
  54.             return 1;  
  55.         }  
  56.         // 从服务器接受数据   
  57.         if(recvfrom(s,bufRecv,BUF_SIZE,0,(SOCKADDR *)&servAddr,&nServerlen) == SOCKET_ERROR)  
  58.         {  
  59.             cout<<"recv failed:"<<WSAGetLastError()<<endl;  
  60.             closesocket(s);  
  61.             WSACleanup();  
  62.             return 1;  
  63.         }  
  64.         cout<<"Recv From Server:"<<bufRecv<<endl;  
  65.     }  
  66.   
  67.     // 关闭套接字,释放资源   
  68.     closesocket(s);  
  69.     WSACleanup();  
  70.     return 0;  
  71. }  
////////////////////////////////////////////////////////////////////////// // SocketOptionClient.cpp // 套接字选项 —— 设置缓冲大小(扩大10倍) #include <iostream.h> #include <winsock2.H> #define BUF_SIZE 64 #pragma comment(lib,"ws2_32.lib") int main(int argc,char* argv[]) { WSADATA wsd; SOCKET s; SOCKADDR_IN servAddr; char bufRecv[BUF_SIZE]; char bufSend[BUF_SIZE]; // 初始化套接字 if(WSAStartup(MAKEWORD(2,2),&wsd)) { cout<<"WSAStartup failed !/n"<<endl; return 1; } // 建立套接字 s = socket(AF_INET,SOCK_DGRAM,0); if(INVALID_SOCKET == s) { cout<<"socket failed !/n"<<endl; WSACleanup(); return 1; } // 缓冲区待发送的数据 ZeroMemory(bufSend,BUF_SIZE); ZeroMemory(bufRecv,BUF_SIZE); strcpy(bufSend,"Hello World !"); // 设置服务器选项 servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = inet_addr("192.168.1.254"); servAddr.sin_port = htons(5000); int nServerlen = sizeof(servAddr); while(1) { // 向服务器发送数据 if(sendto(s,bufSend,BUF_SIZE,0,(SOCKADDR *)&servAddr,nServerlen) == SOCKET_ERROR) { cout<<"sendto failed:"<<WSAGetLastError()<<endl; closesocket(s); WSACleanup(); return 1; } // 从服务器接受数据 if(recvfrom(s,bufRecv,BUF_SIZE,0,(SOCKADDR *)&servAddr,&nServerlen) == SOCKET_ERROR) { cout<<"recv failed:"<<WSAGetLastError()<<endl; closesocket(s); WSACleanup(); return 1; } cout<<"Recv From Server:"<<bufRecv<<endl; } // 关闭套接字,释放资源 closesocket(s); WSACleanup(); return 0; }

 

 

程序运行效果:

套接字选项—修改套接字缓冲区大小_第1张图片

 

 

源码下载地址:

 

http://download.csdn.net/source/1676947

 

你可能感兴趣的:(套接字选项—修改套接字缓冲区大小)