Linux下网络编程(七):socketapi(有关socket 选项)

socket选项

  特意用来读取和设置socket文件描述符属性的方法

#include<sys/socket.h>
int getsockopt(int sockfd,int level, int option_name,void* option_value,socklen_t* restrict option_len);
int setsockopt(int sockfd, int level, int option_name,const void* option_value,sockelen_t option_len);

  参数解释:sockfd指定了被操作的目标socket;level参数指定了要操作的协议的选项,比如IPV4,IPV6,TCP等;option_name指定了选项的名字;option_value和option_len分别表示被操作项的值和长度。这两个函数调用成功时返回0,失败时返回-1,并设置errno
下表中列出了比较常用的socket选项,不同的选项具有不同类型的值:
在这里插入图片描述

sol_socket下的SO_REUSEADDR

  通过socket选项SO_REUSEADDR强制使用被处于TIME_WAIT状态的连接占用的socket地址。代码如下:

int  sock =socket(PF_INET,SOCK_STREAM,0);
assert(sock != -1);
int reuse = 1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse));
struct sockaddr_in addresss;
bzero(&address,sizeof(address));
address.sin_family = AF_INET;
inet_pton(AF_INT,ip,&address.sin_addr);
address.port = htons(port);
bind(sock,(struct sockaddr* )&address,sizeof(address));

可以使处于TIME_WAIT状态的socket地址被立即重用。

SOL_SOCKET 下的SO_RCVBUF和SO_SNDBUF

  这两个选项分别表示了接收缓冲区和发送缓冲区的大小。用setsockopt设置接收和发送缓冲区的大小时,系统会自动将其值加倍,并且不得小于某个值;这样做,是为了TCP接收数据时有足够的缓冲区处理拥塞。
以下是一对客户端和服务器程序,分别修改了TCP发送缓冲区和接收缓冲区的大小。
       修改TCP发送缓冲区的客户端程序

#include<sys/socket.h>
#include<arpa/inet.h>
#include<assert.h>
#include<stdio.h>
#include<unistd.h>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std;
#define buffer 512
int main(int argc, char* argv[])
{
	if(argc <= 2)
	{
		cout<<"usage :"<<base(argv[0])<<"ip address port_number send_buffer_size"<<endl;
		return 1;
	}
	const char* ip = argv[1];
	int port = atoi(argv[2]);
	struct sockaddr_in server_address;
	bzero(&server_address,sizeof(server_address));
	server_address.sin_family = AF_INET;
	inet_pton(AF_INET,ip,&server_address.sin_addr);
	server_address.sin_port = htons(port);
	int sock = socket(PF_INET,SOCK_STREAM,0);
	assert(sock = -1);
	int sendbuf = atoi(argv[3]);
	int len = sizeof(sendbuf);
	setsockopt = (sock,SOL_SOCKET,SO_SNDBUF,&sendbuf,sizeof(sendbuf));
	getsockopt = (sock,SOL_SOCKET,SO_SNDBUF,&sendbuf,(socklen_t*) &len);
	cout<<"the tcp buffer size after setting is "<<sendbuf<<endl;
	if(connect(sock, (struct sockaddr* )&server_address,sizeof(server_address)) !=-1)
	{
		char Buffer[buffer];
		memset(Buffer,'a',buffer);
		send(sock,Buffer,buffer,0);
	}
	close(sock);
	return 0 ;
}

    修改TCP接收缓冲区的服务器程序

#include<sys/socket.h>
#include<netinet.h>
#include<arpa/inet.h>
#include<assert.h>
#include<cstdio>
#include<unistd.h>
#include<cstdlib>
#include<errno.h>
#include<cstring>
using namspace std;
#defing BUFFER_SIZE 1024 
int main()
{
	if (argc <= 2)
	{
	cout<<"usage:"<<basename(argv[0])<<"ip_address port_number recv_beffer_size"<<endl;
	return 1;
}
const char* ip = argv[1];
int port = atoi(argv[2]);
struct sockaddr_in  address;
bzero(&address,sizeof(address));
address.sin_family = AF_INET;
inet_pton(AF_INET,ip,&address.sin_addr);
address.sin_port = htons(port);
int sock = socket(PF_INET,SOCK_STREAM,0);
assert(sock != -1);
int recvbuf = atoi(argv[3]);
int len =sizeof(recvbuf);
setsock(sock, SOL_SOCKET,SO_RCVBUF,&recvbuf,sizeof(recvbuf));
getsock(sock,SOL_SOCKET,SO_RCVBUF,&recvbuf,(socklen_t*)&len);
cout<<"the TCP	receive buffer size after setting is"<<recvbuf<<endl;
int ret = bind(sock,(struct sockaddr*)&address,sizeof(address));
assert(ret != -1);
ret =listen(sock,5);
assert(ret != -1);
struct sockaddr_in client;
socklen_t client_addrlength = sizeof(client);
int connfd = accept(sock,(struct sockaddr*)&client,&client_addrlength);
if(connfd < 0 )
{
	cout<<"errno is"<<errno<<endl;
}
else
{
	char buffer[BUFFER_SIZE];
	memset(buffer,'\0',BUFFER_SIZE);
	while(recv(connfd,buffer,BUFFER_SIZE - 1,0)>0){}
	close(connfd);
}
close(sock);
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值