I/O复用服务器端+回声客户端

并发服务器的第二种实现方法:I/O复用

服务器端:

#include <arpa/inet.h>
#include <unistd.h>
#include <algorithm>
#include <stdio.h>
#include <cstring>
using namespace std;
char buf[1024];
int main(int argc, char **argv)
{
    int ser_sock, cli_sock;
    sockaddr_in ser_addr, cli_addr;
    ser_sock = socket(PF_INET, SOCK_STREAM, 0);
    if(ser_sock == -1) puts("socket error");

    int opt = 1;
    setsockopt(ser_sock, SOL_SOCKET, SO_REUSEADDR, &opt, 4);

    memset(&ser_addr, 0, sizeof(ser_addr));
    ser_addr.sin_family = AF_INET;
    ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    ser_addr.sin_port = htons(atoi(argv[1]));
    if(bind(ser_sock, (sockaddr *)&ser_addr, sizeof(ser_addr)) == -1)
        puts("bind error");

    if(listen(ser_sock, 5) == -1) puts("listen error");

    fd_set fd, copy_fd;
    FD_ZERO(&fd);
    FD_SET(ser_sock, &fd);
    int fd_max = ser_sock;
    timeval timeout;
    socklen_t s_len = sizeof(cli_addr);
    while(1)
    {
        timeout.tv_sec = 5;
        timeout.tv_usec = 0;
        copy_fd = fd;
        int fd_num = select(fd_max+1, &copy_fd, 0, 0, &timeout);
        if(fd_num == 0) continue;
        for(int i = 0; i <= fd_max; i++)
        {
            if(FD_ISSET(i, &copy_fd))
            {
                if(i == ser_sock)//accept时服务器套接字发生变化
                {
                    cli_sock = accept(ser_sock, (sockaddr *)&cli_addr, &s_len);
                    FD_SET(cli_sock, &fd);
                    fd_max = max(fd_max, cli_sock);
                }
                else            //传输数据时客户端套接字发生变化
                {
                    int len = read(i, buf, 100);
                    if(!len)     //eof时删除fd数组信息并关闭套接字
                    {
                        close(i);
                        FD_CLR(i, &fd);
                        printf("close client %d\n", i);
                    }
                    else
                    {
                        buf[len] = 0;
                        printf("message form client %d : %s\n", i, buf);
                        write(i, buf, 100);
                    }
                }
            }
        }        
    }
    close(ser_sock);
    return 0;
}

客户端:

#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <algorithm>
#include <cstring>
using namespace std;
int main(int argc, char **argv)
{
    int sock;
    sock = socket(PF_INET, SOCK_STREAM, 0);
    sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(argv[1]);
    addr.sin_port = htons(atoi(argv[2]));
    connect(sock, (sockaddr *)&addr, sizeof(addr));
    char buf[1024];
    while(1)
    {
        scanf("%s", buf);
        int l = strlen(buf);
        if(strcmp(buf, "q") == 0) break;
        write(sock, buf, l);
        sleep(0.5);
        int len = read(sock, buf, 100);
        buf[len] = 0;
        printf("message from server : %s\n", buf);
    }
    close(sock);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lesroad/p/9641399.html