Linux setsockopt和getsockopt函数的用法分析

套接字机制提供两个套接字选项来控制套接字行为。一个接口用来控制选项,另一个接口允许查询一个选项的状态。

1 #include <sys/types.h>
2 #include <sys/socket.h>
3
4 int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
5 int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
6 返回值:若成功则返回0,若出错则返回-1

参数说明:

sockfd:必须指向一个打开的套接字描述符。

level:标识了选项应用的协议。

optname:要设置或获取套接字选项的名字。

optval:指向函数设置或获取值得地址,即保存选项值的缓存区。

optlen:指定了optval指向的对象的大小。


示例1:使用选项SO_RCVBUF和SO_SNDBUF获取缓冲区大小

server.c

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<sys/types.h>
 4 #include<sys/socket.h>
 5 #include<unistd.h>
 6 #include<arpa/inet.h>
 7 #include<netinet/in.h>
 8 #include<string.h>
 9 #include<errno.h>
10
11 #define N 64
12 #define err_log(log) do{ perror(log); exit(1);}while(0)
13
14 int main(int argc, const char *argv[])
15 {
16     int sockfd, connectfd;
17     char buf[N];
18     struct sockaddr_in serveraddr, clientaddr;
19     int optval;
20     socklen_t optlen = sizeof(optval);
21     socklen_t len = sizeof(clientaddr);
22
23     if(argc != 3)
24     {
25         fprintf(stderr, "Usage:%s serverip port", argv[0]);
26         return -1;
27     }
28     sockfd = socket(AF_INET, SOCK_STREAM, 0);
29     if(sockfd < 0)
30         err_log("fail to sockfd");
31
32     serveraddr.sin_family = AF_INET;
33     serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
34     serveraddr.sin_port = htons(atoi(argv[2]));
35
36     if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen) < 0)
37         err_log("fail to getsockopt");
38     printf("SO_SNDBUF:%d K\n", optval/1024);
39
40     if(getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &optval, &optlen) < 0)
41         err_log("fail to getsockopt");
42     printf("SO_RCVBUF:%d K\n", optval/1024);
43
44     if(bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
45         err_log("fail to bind");
46     if(listen(sockfd, 5) < 0)
47         err_log("fail to listen");
48     if((connectfd = accept(sockfd, (struct sockaddr*)&clientaddr, &len)) < 0)
49         err_log("fail to connectfd");
50
51     printf("client:%s--->%d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
52
53     while(1)
54     {
55         if(recv(connectfd, buf, N, 0) < 0)
56             err_log("fail to recv");
57         if(strncmp(buf, "quit", 4) == 0)
58             break;
59         buf[strlen(buf) - 1] = ‘\0‘;
60         printf("buf:%s\n", buf);
61         strcat(buf, "+++***---");
62         if(send(connectfd, buf, N, 0) < 0)
63             err_log("fail to send");
64     }
65     close(connectfd);
66     close(sockfd);
67     return 0;
68 }

client.c

 1 #include<stdio.h>
 2 #include<sys/types.h>
 3 #include<sys/socket.h>
 4 #include<unistd.h>
 5 #include<arpa/inet.h>
 6 #include<netinet/in.h>
 7 #include<string.h>
 8 #include<stdlib.h>
 9 #include<errno.h>
10
11 #define N 64
12 #define err_log(log) do{perror(log); exit(1);}while(0)
13
14 int main(int argc, const char *argv[])
15 {
16     int sockfd;
17     struct sockaddr_in serveraddr;
18     char buf[N];
19
20     if(argc != 3)
21     {
22         fprintf(stderr, "Usage:%s serverip port.", argv[1]);
23         return -1;
24     }
25     sockfd = socket(AF_INET, SOCK_STREAM, 0);
26     if(sockfd < 0)
27         err_log("fail to sockfd");
28
29     serveraddr.sin_family = AF_INET;
30     serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
31     serveraddr.sin_port = htons(atoi(argv[2]));
32     if(connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
33         err_log("fail to connect");
34
35     while(1)
36     {
37         printf("<client>");
38         fgets(buf, N, stdin);
39         if(send(sockfd, buf, N, 0) < 0)
40             err_log("fail to send");
41         if(strncmp(buf, "quit", 4) == 0)
42             break;
43         if(recv(sockfd, buf, N, 0) < 0)
44             err_log("fail to recv");
45         printf("buf:%s\n", buf);
46     }
47     close(sockfd);
48     return 0;
49 }

服务器运行结果:

客户端运行结果:

示例2:使用选项SO_RCVTIMEO超时接收

server.c

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<sys/types.h>
 4 #include<sys/socket.h>
 5 #include<unistd.h>
 6 #include<netinet/in.h>
 7 #include<arpa/inet.h>
 8 #include<string.h>
 9 #include<errno.h>
10
11 #define N 64
12 #define err_log(log) do{ perror(log); exit(1);}while(0)
13
14 int main(int argc, const char *argv[])
15 {
16     int sockfd, connectfd;
17     char buf[N];
18     struct sockaddr_in serveraddr, clientaddr;
19     socklen_t len = sizeof(clientaddr);
20     struct timeval tv;
21     socklen_t optlen = sizeof(tv);
22
23     if(argc != 3)
24     {
25         fprintf(stderr, "Usage:%s serverip port", argv[0]);
26         return -1;
27     }
28
29     sockfd = socket(AF_INET, SOCK_STREAM, 0);
30     if(sockfd < 0)
31         err_log("fail to sockfd");
32
33     serveraddr.sin_family = AF_INET;
34     serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
35     serveraddr.sin_port = htons(atoi(argv[2]));
36
37     tv.tv_sec = 5;
38     tv.tv_usec = 0;
39     if(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, optlen) < 0)
40         err_log("fail to setsockopt");
41
42     if(bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
43         err_log("fail to bind");
44
45     if(listen(sockfd, 5) < 0)
46         err_log("fail to listen");
47
48     if((connectfd = accept(sockfd, (struct sockaddr*)&clientaddr, &len)) < 0)
49     {
50         if(errno == 11)
51         {
52             printf("errno = %d--->%s\n", errno, strerror(errno));
53         }
54         else
55         {
56             err_log("fail to accept");
57         }
58     }
59     printf("client:%s--->%d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
60     while(1)
61         {
62             if(recv(connectfd, buf, N, 0) < 0)
63                 err_log("fail to recv");
64             if(strncmp(buf, "quit", 4) == 0)
65                 break;
66             buf[strlen(buf) - 1] = ‘\0‘;
67             printf("buf:%s\n", buf);
68         }
69     close(connectfd);
70     close(sockfd);
71     return 0;
72 }

client.c

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<sys/types.h>
 4 #include<sys/socket.h>
 5 #include<unistd.h>
 6 #include<arpa/inet.h>
 7 #include<netinet/in.h>
 8 #include<string.h>
 9 #include<errno.h>
10
11 #define N 64
12 #define err_log(log) do{perror(log); exit(1);}while(0)
13
14 int main(int argc, const char *argv[])
15 {
16     int sockfd;
17     char buf[N];
18     struct sockaddr_in serveraddr;
19
20     if(argc != 3)
21     {
22         fprintf(stderr, "Usage:%s serverip port.", argv[0]);
23         return -1;
24     }
25
26     sockfd = socket(AF_INET, SOCK_STREAM, 0);
27     if(sockfd < 0)
28         err_log("fail to sockfd");
29
30     serveraddr.sin_family = AF_INET;
31     serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
32     serveraddr.sin_port = htons(atoi(argv[2]));
33
34     if(connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
35         err_log("fail to connect");
36
37     while(1)
38     {
39         printf("<client>");
40         fgets(buf, N, stdin);
41         if(send(sockfd, buf, N, 0) < 0)
42             err_log("fail to send");
43         if(strncmp(buf, "quit", 4) == 0)
44             break;
45     }
46     close(sockfd);
47     return 0;
48 }

运行程序如下:

(1)正常运行/退出

服务器端:

客服端:

(2)当正常发送/接收数据时,客户端停止发送,服务器端在设定5s后退出

服务器端:

客户端:

(3)客户端不连接服务器,那么服务器会在设置的5s后退出

服务器端:

时间: 2024-10-06 13:37:26

Linux setsockopt和getsockopt函数的用法分析的相关文章

java String.split()函数的用法分析

在java.lang包中有String.split()方法的原型是:public String[] split(String regex, int limit)split函数是用于使用特定的切割符(regex)来分隔字符串成一个字符串数组,函数返回是一个数组.在其中每个出现regex的位置都要进行分解.需要注意是有以下几点:(1)regex是可选项.字符串或正则表达式对象,它标识了分隔字符串时使用的是一个还是多个字符.如果忽略该选项,返回包含整个字符串的单一元素数组.(2)limit也是可选项.

判断类是否存在函数class_exists用法分析

原文地址:判断类是否存在函数class_exists用法分析 如果我们要判断一个类是不是可以用,可以先使用class_exists函数来判断一下,下面来看几个例子. bool class_exists ( string $class_name [, bool $autoload = true ] ) 此功能是否给定的类被定义检查.this function checks whether or not the given class has been defined.返回true,如果class_

setsockopt()和getsockopt()函数参数

setsockopt()函数功能介绍 功能描述: 获取或者设置与某个套接字关联的选项.选项可能存在于多层协议中,它们总会出现在最上面的套接字层.当操作套接字选项时,选项位于的层和选项的名称必须给出.为了操作套接字层的选项,应该 将层的值指定为SOL_SOCKET.为了操作其它层的选项,控制选项的合适协议号必须给出.例如,为了表示一个选项由TCP协议解析,层应该设定为协议 号TCP. getsockopt()函数功能是获取一个套接口选项. 原型: int getsockopt(int sock,

linux下dup/dup2函数的用法

系统调用dup和dup2能够复制文件描述符.dup返回新的文件文件描述符(没有用的文件描述符最小的编号).dup2可以让用户指定返回的文件描述符的值,如果需要,则首先接近newfd的值,他通常用来重新打开或者重定向一个文件描述符. 他的原型如下: #include <unsitd.h> int dup(int oldfd); int dup2(int oldfd,int newfd); dup 和dup2都是返回新的描述符.或者返回-1并设置 errno变量.新老描述符共享文件的偏移量(位置)

。。。Java String.split()函数的用法分析。。。

在java.lang包中有String.split()方法的原型是:public String[] split(String regex, int limit) split函数是用于使用特定的切割符(regex)来分隔字符串成一个字符串数组,函数返回是一个数组.在其中每个出现regex的位置都要进行分解. 需要注意是有以下几点: (1)regex是可选项.字符串或正则表达式对象,它标识了分隔字符串时使用的是一个还是多个字符.如果忽略该选项,返回包含整个字符串的单一元素数组. (2)limit也是

Linux 下函数栈帧分析

1.关于栈 对于程序,编译器会对其分配一段内存,在逻辑上可以分为代码段,数据段,堆,栈 代码段:保存程序文本,指令指针EIP就是指向代码段,可读可执行不可写 数据段:保存初始化的全局变量和静态变量,可读可写不可执行 BSS:未初始化的全局变量和静态变量 堆(Heap):动态分配内存,向地址增大的方向增长,可读可写可执行 栈(Stack):存放局部变量,函数参数,当前状态,函数调用信息等,向地址减小的方向增长,非常非常重要,可读可写可执行.如下图所示: 首先必须明确一点也是非常重要的一点,栈是向下

linux 非阻塞 connect函数

开发测试环境:虚拟机CentOS,windows网络调试助手        非阻塞模式有3种用途        1.三次握手同时做其他的处理.connect要花一个往返时间完成,从几毫秒的局域网到几百毫秒或几秒的广域网.这段时间可能有一些其他的处理要执行,比如数据准备,预处理等.        2.用这种技术建立多个连接.这在web浏览器中很普遍.        3.由于程序用select等待连接完成,可以设置一个select等待时间限制,从而缩短connect超时时间.多数实现中,connec

pthread_cond_wait()用法分析

很久没看APUE,今天一位朋友问道关于一个mutex的问题,又翻到了以前讨论过的东西,为了不让自己忘记,把曾经的东西总结一下. 先大体看下网上很多地方都有的关于pthread_cond_wait()的说明: 条件变量           条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起:另一个线程使"条件成立"(给出条件成立信号).为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起.       

linux下 signal信号机制的透彻分析与各种实例讲解

转自:http://blog.sina.com.cn/s/blog_636a55070101vs2d.html 转自:http://blog.csdn.net/tiany524/article/details/17048069 首先感谢上述两位博主的详细讲解. 虽然内容有点长,但是分析的很全面,各种实例应用基本都考虑到了. 本文将从以下几个方面来阐述信号: (1)信号的基本知识 (2)信号生命周期与处理过程分析 (3) 基本的信号处理函数 (4) 保护临界区不被中断 (5) 信号的继承与执行 (