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

转自:点击打开链接


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

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 
=========================================================================

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

//
// 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;
}

//
// 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;
}

程序运行效果:

套接字选项



  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值