9.1 套接字可选性和IO缓冲大小

1. 之前使用的套接字都是使用默认的配置,有些情况需要变更套接字配置,配置项如下:



IPPROTO_IP层是IP协议相关事项,IPPROTO_TCP层可选项是TCP协议相关事项,SOL_SOCKET是套接字相关的通用可选项。

2. 读取选项函数getsockopt

#include <sys/socket.h>

int getsockopt(int sock,int level, int optname,void *optval,socklen_t *optlen);

成功返回0,错误-1

sock:用于查看选项的套接字文件描述符
level:要查看的可选项的协议层
optname:可选项名称
optval:保存查看结果的缓冲地址值
optlen:optval缓冲大小

3. 设置选项函数setsockopt

#include <sys/socket.h>

int setsockopt(int sock,int level, int optname,const void *optval,socklen_t *optlen);

成功返回0,错误-1

sock:用于设置选项的套接字文件描述符
level:要设置的可选项的协议层
optname:可选项名称
optval:保存查看结果的缓冲地址值
optlen:optval缓冲大小

4. 示例一,查看SO_TYPE

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>

void error_handling(char *message);

int main(int argc, char *argv[]){
    int tcp_sock,udp_sock;
    int sock_type;
    socklen_t optlen;
    int state;

    optlen = sizeof(sock_type);
    tcp_sock = socket(PF_INET,SOCK_STREAM,0);
    udp_sock = socket(PF_INET,SOCK_DGRAM,0);

    printf("STREAM: %d \n",SOCK_STREAM);
    printf("DGRAM: %d \n",SOCK_DGRAM);

    state = getsockopt(tcp_sock,SOL_SOCKET,SO_TYPE,(void *)&sock_type,&optlen);
    if(state){
	error_handling("getsockopt error");
    }
    printf("socket type one: %d \n",sock_type);

    state = getsockopt(udp_sock,SOL_SOCKET,SO_TYPE,(void *)&sock_type,&optlen);
    if(state){
	error_handling("getsockopt error");
    }
    printf("socket type two: %d \n",sock_type);
}

void error_handling(char *message){
    fputs(message,stderr);
    fputs("\n",stderr);
    exit(1);
}

执行结果:

alex@alex-virtual-machine:/extra/tcpip$ ./a.out
STREAM: 1
DGRAM: 2
socket type one: 1
socket type two: 2
5. 示例二,查看输入输出缓冲大小

代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>

void error_handling(char *message);

int main(int argc, char *argv[]){
    int sock;
    int snd_buf,rcv_buf,state;
    socklen_t len;

    sock = socket(PF_INET,SOCK_STREAM,0);

    len = sizeof(snd_buf);

    state = getsockopt(sock,SOL_SOCKET,SO_SNDBUF,(void *)&snd_buf,&len);
    if(state){
	error_handling("getsockopt error");
    }

    len = sizeof(rcv_buf);
    state = getsockopt(sock,SOL_SOCKET,SO_RCVBUF,(void *)&rcv_buf,&len);
    if(state){
	error_handling("getsockopt error");
    }

    printf("Input buffer size : %d \n",rcv_buf);
    printf("Output buffer size : %d \n",snd_buf);

    return 0;
}

void error_handling(char *message){
    fputs(message,stderr);
    fputs("\n",stderr);
    exit(1);
}

执行结果:

alex@alex-virtual-machine:/extra/tcpip$ gcc get_buf.c
alex@alex-virtual-machine:/extra/tcpip$ ./a.out
Input buffer size : 87380
Output buffer size : 16384

6. 设置缓冲大小,根据实际情况设定:

代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>

void error_handling(char *message);

int main(int argc, char *argv[]){
    int sock;
    int snd_buf= 1024*3,rcv_buf = 1024*3,state;
    socklen_t len;

    sock = socket(PF_INET,SOCK_STREAM,0);

    state = setsockopt(sock,SOL_SOCKET,SO_RCVBUF,(void *)&rcv_buf,sizeof(rcv_buf));
    if(state){
	error_handling("setsockopt error");
    }

    state = setsockopt(sock,SOL_SOCKET,SO_SNDBUF,(void *)&snd_buf,sizeof(snd_buf));
    if(state){
	error_handling("setsockopt error");
    }

    len = sizeof(snd_buf);
    state = getsockopt(sock,SOL_SOCKET,SO_SNDBUF,(void *)&snd_buf,&len);

    len = sizeof(rcv_buf);
    state = getsockopt(sock,SOL_SOCKET,SO_RCVBUF,(void *)&rcv_buf,&len);
    printf("Input buffer size : %d \n",rcv_buf);
    printf("Output buffer size : %d \n",snd_buf);

    return 0;
}

void error_handling(char *message){
    fputs(message,stderr);
    fputs("\n",stderr);
    exit(1);
}

执行结果:

alex@alex-virtual-machine:/extra/tcpip$ gcc set_buf.c
alex@alex-virtual-machine:/extra/tcpip$ ./a.out
Input buffer size : 6144
Output buffer size : 6144
结果并非完全符合设定预期,会有所差别。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值