有时候我们需要控制套接字的行为(如修改缓冲区的大小),这个时候我们就要学习套接字选项。
[cpp] view plain copy print ?
- 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)
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 ?
-
-
-
-
- #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);
-
-
- nErrorCode = getsockopt(s,SOL_SOCKET,SO_RCVBUF,(char*)&nBufLen,&nOptLen);
- if(SOCKET_ERROR == nErrorCode)
- {
- cout<<"getsockopt failed !/n"<<endl;
- WSACleanup();
- return 1;
- }
-
-
- nBufLen *= 10;
- nErrorCode = setsockopt(s,SOL_SOCKET,SO_RCVBUF,(char*)&nBufLen,nOptLen);
- if(SOCKET_ERROR == nErrorCode)
- {
- cout<<"setsockopt failed !/n"<<endl;
- WSACleanup();
- return 1;
- }
-
-
- 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;
- }
////////////////////////////////////////////////////////////////////////// // 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 ?
-
-
-
-
- #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;
- }
////////////////////////////////////////////////////////////////////////// // 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; }
程序运行效果:
源码下载地址:
http://download.csdn.net/source/1676947