美文网首页
C语言socket poll编程

C语言socket poll编程

作者: 一路向后 | 来源:发表于2020-07-12 20:52 被阅读0次

1.server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <poll.h>
#include <signal.h>
#include <limits.h>
#include <errno.h>

#define POLLRDNORM 0x040
#define MAX_LINE 5
#define OPEN_MAX 1024

typedef struct sockaddr SA;

int main()
{
        struct sockaddr_in srv_addr, cli_addr;
        struct pollfd client[OPEN_MAX];
        char buf[MAX_LINE];
        ssize_t n;
        int listenfd, connfd, sockfd, i, max;
        int nready;
        int cli_len;
        int ret;

        /*创建监听套接字*/
        if((listenfd=socket(AF_INET, SOCK_STREAM, 0)) < 0)
        {
                printf("socket() error!");
                exit(0);
        }

        /*对协议地址进行清零*/
        bzero(&srv_addr, sizeof(srv_addr));

        srv_addr.sin_family = AF_INET;
        srv_addr.sin_port = htons(8080);
        srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

        /*绑定套接字到本地端口*/
        if(bind(listenfd, (SA *)&srv_addr, sizeof(srv_addr)) < 0)
        {
                printf("bind() error!");
                exit(0);
        }

        /*服务器开始监听*/
        if(listen(listenfd, 5) < 0)
        {
                printf("listen() error!");
                exit(0);
        }

        client[0].fd = listenfd;
        client[0].events = POLLIN;

        for(i=1; i<OPEN_MAX; i++)
        {
                client[i].fd = -1;
        }

        max = 0;

        while(1)
        {
                nready = poll(client, max+1, -1);

                if(client[0].revents & POLLIN)
                {
                        cli_len = sizeof(cli_addr);

                        printf("accept begin\n");

                        connfd = accept(listenfd, (SA *)&cli_addr, &cli_len);
                        if(connfd < 0)
                        {
                                continue;
                        }

                        for(i=1; i<OPEN_MAX; i++)
                        {
                                if(client[i].fd < 0)
                                {
                                        client[i].fd = connfd;
                                        break;
                                }
                        }

                        printf("accept end %d\n", connfd);

                        if(i == OPEN_MAX)
                        {
                                printf("too many clients");
                                exit(0);
                        }

                        client[i].events = POLLIN;

                        if(i > max)
                        {
                                max = i;
                        }

                        if(--nready <= 0)
                        {
                                continue;
                        }
                }

                for(i=1; i<OPEN_MAX; i++)
                {
                        if((sockfd=client[i].fd) < 0)
                        {
                                continue;
                        }

                        if(client[i].revents & POLLIN | POLLERR)
                        {
                                if((n=read(sockfd, buf, MAX_LINE)) < 0)
                                {
                                        if(errno == ECONNRESET)
                                        {
                                                close(sockfd);
                                                client[i].fd = -1;
                                        }
                                        else
                                        {
                                                printf("read error!");
                                        }
                                }
                                else if(n == 0)
                                {
                                        close(sockfd);
                                        client[i].fd = -1;
                                }
                                else
                                {
                                        printf("buf=%s\n", buf);
                                        write(sockfd, buf, n);
                                }

                                if(--nready <= 0)
                                        break;
                        }
                }
        }

        return 0;
}

2.client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <errno.h>

int main()
{
        struct sockaddr_in address;
        char ch = 'A';
        int cli_fd;
        int len;
        int ret;

        cli_fd = socket(AF_INET, SOCK_STREAM, 0);

        address.sin_family = AF_INET;
        address.sin_addr.s_addr = inet_addr("127.0.0.1");
        address.sin_port = htons(8080);

        len = sizeof(address);

        ret = connect(cli_fd, (struct sockaddr *)&address, len);
        if(ret == -1)
        {
                perror("oops: client2");
                exit(-1);
        }

        /*第一次读写*/
        write(cli_fd, &ch, 1);
        read(cli_fd, &ch, 1);

        printf("the first time: char from server = %c\n", ch);

        sleep(5);

        /*第二次读写*/
        ch = 'B';
        write(cli_fd, &ch, 1);
        read(cli_fd, &ch, 1);

        printf("the second time: char from server = %c\n", ch);

        close(cli_fd);

        return 0;
}

3.编译程序

$ gcc -o server server.c
$ gcc -o client client.c

4.运行程序

$ ./server 
accept begin
accept end 4
buf=A
buf=B
$ ./client 
the first time: char from server = A
the second time: char from server = B

相关文章

网友评论

      本文标题:C语言socket poll编程

      本文链接:https://www.haomeiwen.com/subject/ikbzcktx.html