llinux C练习十 Tcp通信select实现简易聊天

用select 和Tcp通信实现服务器和客户端两者的聊天

//TcpChatServer.c
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define RET_VAL(VAL,FUNC_NAME) do{\
                    if(VAL < 0) \
                    {\
                        perror(#FUNC_NAME);\
                        exit(-1);\
                    }\
                }\
                while(0)
int main(int argc, char * argv[])
{
    int sock_fd;
    int client_fd;
    int maxfd;
    int ret;
    fd_set readfdset;
    struct timeval timeout;
    struct sockaddr_in addr;
    struct sockaddr_in clientaddr;
    struct in_addr inaddr;
    int addrlen = sizeof(clientaddr);
    char message[200];
    char * sendstr= "hello server\n";
    addr.sin_family = AF_INET;
    addr.sin_port = htons(3456);
    ret = inet_aton("127.0.0.1",&inaddr);
    RET_VAL(ret,inet_aton);
    addr.sin_addr = inaddr;

    sock_fd = socket(AF_INET,SOCK_STREAM,0);
    ret = bind(sock_fd,(struct sockaddr*) &addr,sizeof(addr));
    if(ret < 0)
    {
        perror("bind");
        exit(-1);
    }

    ret = listen(sock_fd,5);
    RET_VAL(ret,listen);
    timeout.tv_sec = 5;
    timeout.tv_usec = 5000;
    client_fd = accept(sock_fd,(struct sockaddr*)&clientaddr,&addrlen);
    bzero(message,sizeof(message));

    while(1)
    {
        timeout.tv_sec = 5;
        timeout.tv_usec = 5000;
        FD_ZERO(&readfdset);
        FD_SET(client_fd,&readfdset);
        FD_SET(0,&readfdset); 
        maxfd = (client_fd > sock_fd ) ? client_fd : sock_fd;
        ret = select(client_fd+1,&readfdset,NULL,NULL,&timeout);
        if(ret < -1)
        {
            perror("select");
        }
        else if(0 == ret)
        {
            printf("time is over\n");
        }
        else
        {
            if(FD_ISSET(client_fd,&readfdset))
            {
                bzero(message,sizeof(message));
                ret = recv(client_fd,message,sizeof(message),0);
                RET_VAL(ret,recv);
                if(0 == strncmp(message,"close",5))
                {
                    break;
                }
                if(ret == 0)
                {
                    printf("connect break\n");
                    break;
                }
                printf("%s",message);
            }
            if(FD_ISSET(0,&readfdset))
            {
                ret = read(0,message,sizeof(message));
                if(ret < 0)
                {
                    perror("read");
                }
                else
                {
                    message[ret] = '\0';
                }
                printf("%s\n",message);
                send(client_fd,message,strlen(message),0);
            }
        }
        printf("timtout.tv_sec=%d\n",timeout.tv_sec);

    }
    printf("while exit\n");
    ret = recv(client_fd,message,sizeof(message),0);
    RET_VAL(ret,recv);
    printf("%s",message);
    ret = send(client_fd,sendstr,strlen(sendstr),0);
    RET_VAL(ret,send);
    printf("send string success\n");
    close(client_fd);
    close(sock_fd);
}



//TcpChatClient.c
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define RET_VAL(VAL,FUNC_NAME) do{\
                    if(VAL < 0) \
                    {\
                        perror(#FUNC_NAME);\
                        exit(-1);\
                    }\
                }\
                while(0)
int main(int argc, char * argv[])
{
    int sock_fd;
    int client_fd;
    int ret;
    struct timeval timeout;
    fd_set readfdset;
    struct sockaddr_in addr;
    struct sockaddr_in clientaddr;
    struct in_addr inaddr;
    int addrlen = sizeof(clientaddr);
    char message[200];
    char * sendstr= "hello client\n";
    addr.sin_family = AF_INET;
    addr.sin_port = htons(3456);
    ret = inet_aton("127.0.0.1",&inaddr);
    RET_VAL(ret,inet_aton);
    addr.sin_addr = inaddr;

    sock_fd = socket(AF_INET,SOCK_STREAM,0);

    ret = connect(sock_fd,(struct sockaddr*)&addr,sizeof(addr));
    RET_VAL(ret,connect);
    bzero(message,sizeof(message));
//    ret = recv(client_fd,message,sizeof(message),0);
//    RET_VAL(ret,recv);
//    printf("%s",message);
    while(1)
    {
        timeout.tv_sec = 5;
        timeout.tv_usec = 5000000;
        FD_ZERO(&readfdset);
        FD_SET(sock_fd,&readfdset);
        FD_SET(0,&readfdset);
        ret = select(sock_fd+1,&readfdset,NULL,NULL,&timeout);
        if(ret < 0)
        {
            perror("select");
        }
        else if(0 == ret)
        {
            printf("time is over\n");
        }
        else
        {
            if(FD_ISSET(0,&readfdset))
            {
                printf("select ok\n");
                ret = read(0,message,sizeof(message));
                if(ret < 0)
                {
                    perror("read");
                }
                send(sock_fd,message,strlen(message),0);
                if(0 == strncmp(message,"close",5))
                {
                    break;
                }
            }
            if(FD_ISSET(sock_fd,&readfdset))
            {
                ret = recv(sock_fd,message,sizeof(message),0);
                if(0 == ret)
                {
                    printf("server not in work\n");
                    break;
                }
                else
                {
                    message[ret] = '\0';
                    printf("recv:%s\n",message);
                }
            }
        }
    }
    ret = send(sock_fd,sendstr,strlen(sendstr),0);
    RET_VAL(ret,send);
    printf("send string success\n");
    
//    ret = recv(sock_fd,message,sizeof(message),0);
//    printf("recv from ser:%s",message);
    close(sock_fd);
}




你可能感兴趣的:(C,百炼成钢)