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
结果并非完全符合设定预期,会有所差别。