`
memorymyann
  • 浏览: 265739 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

12.套接口选项:套接口低潮限度

阅读更多

之前曾经提到过这个名词,套接口低潮限度。(以下都只针对TCP)

 

接收低潮限度(SO_RCVLOWAT):之前我们曾经使用过select函数,如果将套接口可读,也就是说套接口中有数据可以读出做为select的一个阻塞条件,则什么叫做有数据可读?其实就是指套接口中数据大小大于低潮限度。默认的低潮大小为1,也就是只要有数据到达就表示可读。

 

发送低潮限度(SO_SNDLOWAT):和上面一样,就是当你想对某个套接口执行write时候,如果空闲大小大于等于低潮限度就表示可写,也就是会从select函数返回。比如说下面的程序

#include "/programe/net/head.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "sys/wait.h"
#include "sys/select.h"
#include "sys/time.h"

#define MAXSIZE 100
#define LISTENQ 10

int main(int argc, char ** argv) {
        int listenfd, connfd;
        socklen_t client_len;
        struct sockaddr_in client_socket, serv_socket;
        char send[MAXSIZE + 1], recv[MAXSIZE + 1];


        listenfd = socket(AF_INET, SOCK_STREAM, 0);

        bzero(&serv_socket, sizeof(serv_socket));
        serv_socket.sin_family = AF_INET;
        serv_socket.sin_addr.s_addr = htonl(INADDR_ANY);
        serv_socket.sin_port = htons(atoi(argv[1]));
        bind(listenfd, (struct sockaddr *)&serv_socket, sizeof(serv_socket));
        listen(listenfd, LISTENQ);
        client_len = sizeof(client_socket);
        connfd = accept(listenfd, (struct sockaddr *)&client_socket, &client_len);
        int recv_min_size = 6;
        int flag = setsockopt(connfd, SOL_SOCKET, SO_RCVLOWAT, (void *)&recv_min_size, sizeof(int));

        //设置接受低潮
        int recv_min_size1;
        socklen_t recv_min_len = sizeof(recv_min_size1);
        getsockopt(connfd, SOL_SOCKET, SO_RCVLOWAT, (void *)&recv_min_size1, &recv_min_len);
        if(flag >= 0)
                printf("set SO_RCVLOWAT OK!!! SO_RCVLOWAT = %d\n", recv_min_size1);
        else
                printf("set SO_RCVLOWAT failed!!! SO_RCVLOWAT = %d\n", recv_min_size1);
        for(;;) {
                fd_set rest;
                FD_ZERO(&rest);
                FD_SET(1, &rest);
                FD_SET(connfd, &rest);
                int maxfdpl = 2;
                if(maxfdpl < connfd + 1)
                        maxfdpl = connfd + 1;
                int flag = select(maxfdpl, &rest, NULL, NULL, NULL); //  2
                if(flag <= 0) {
                        printf("some error happend, sorry");
                } else {
                        if(FD_ISSET(1, &rest)) {
                                int n = read(1, send, MAXSIZE);
                                send[n] = '\0';
                                write(connfd, send, n);
                        }
                        if(FD_ISSET(connfd, &rest)) {
                                int n = read(connfd, recv, MAXSIZE);
                                if(n == 0) {
                                        printf("client closed\n");
                                        break;
                                }
                                recv[n] = '\0';
                                printf("get message:%s", recv);
                        }
                }

        }
}

和之前的代码没有什么不同,只是增加了设置接受低潮。下面是客户端代码:

#include "/programe/net/head.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/select.h"

#define MAXSIZE 100

int main(int argc, char ** argv) {
        int sockfd;
        struct sockaddr_in serv_socket;
        int maxfdpl;
        char send[MAXSIZE], recv[MAXSIZE];

        if(argc != 2) {
                printf("please input port");
                exit(1);
        }

        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        bzero(&serv_socket, sizeof(serv_socket));
        serv_socket.sin_family = AF_INET;
        serv_socket.sin_port = htons(atoi(argv[1]));
        inet_pton(AF_INET, "192.168.1.235", &serv_socket.sin_addr);
        connect(sockfd, (struct sockaddr *)&serv_socket, sizeof(serv_socket));
        for(;;) {
                fd_set rset;
                FD_ZERO(&rset);
                FD_SET(1, &rset);
                FD_SET(sockfd, &rset);
                maxfdpl = sockfd + 1;
                select(maxfdpl, &rset, NULL, NULL, NULL); //  1
                if(FD_ISSET(sockfd, &rset)) {
                        int n = read(sockfd, recv, MAXSIZE);
                        if(!n) {
                                printf("server closed\n");
                                break;
                        }
                        recv[n] = '\0';
                        printf("get message from server:%s\n", recv);
                }
                if(FD_ISSET(1, &rset)) {
                        int n = read(1, send, MAXSIZE);
                        send[n] = '\0';
                        write(sockfd, send, n);
                }
        }
        close(sockfd);
        exit(0);
}

运行就会发现如果你输入的字符个数少于6(包括回车),select会继续阻塞。(注:我测试了一下,低潮限度只是会对select造成影响,不会对read和write函数的阻塞造成影响)

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics