Socket——实现简单的一对一服务器端与客户端聊天功能

15 篇文章 0 订阅
3 篇文章 0 订阅

server.c

/* Socket head file */
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>/*sockaddr_in{} */
#include<arpa/inet.h>

/* Unix standard head file */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>

#include <errno.h>/*strerror(),perror(),errno head file*/
#include <sys/time.h>
#include <sys/wait.h> 

#define PORT     9999

#define MAX_BUFF 1024
#define LISTENQ  1024

int main (int argc, char **argv)
{
    int sockfd;
    int new_fd;
    socklen_t len;
    int retval;
    int maxfd = -1;
    unsigned int value = 1;

    fd_set rfds; 

    struct sockaddr_in my_addr;
    struct sockaddr_in t_addr;
    struct timeval tv;

    int my_port;

    char buf[MAX_BUFF];

    if(2 == argc)
    {
        my_port = atoi(argv[1]);
    }
    else
    {
        my_port = PORT;
    }

    /* Use Socket() function*/
    if((sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
    {
        perror("Socket error");
        exit(1);
    }

    memset(&my_addr,0,sizeof(my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(my_port);
    my_addr.sin_addr.s_addr = INADDR_ANY;

    /*Use bind() function*/
    setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(void *)&value,sizeof(value)); 
    if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(my_addr))<0)
    {
        perror("bind error");
        exit(1);
    }

    /* Use listen() function */
    if(listen(sockfd,LISTENQ)<0)
    {
        perror("listen error");
        exit(1);
    }

    /* Start to connect... */
    while(1)
    {
        printf("waiting for new connecting to start new char:\n");
        len = sizeof(struct sockaddr);
        if((new_fd = accept(sockfd,(struct sockaddr *)&t_addr,&len))<0)
        {
            perror("accept error");
            exit(errno);
        }
        else
        {
            printf("server got connection from:%s,por t%d,socked %d\n",inet_ntoa(t_addr.sin_addr),ntohs(t_addr.sin_port),new_fd);
        }
        /* Start processing the data on new connection */
        while(1)
        {   
            /* Set empty */
            FD_ZERO(&rfds);
            /* Add the standard input handle 0 */
            FD_SET(0,&rfds);
            maxfd = 0;
            /*Add the current connection handle new_fd */
            FD_SET(new_fd,&rfds);
            if(new_fd > maxfd)
            {
                maxfd = new_fd;
            }
            /* Set maximum waiting time */
            tv.tv_sec = 1;
            tv.tv_usec = 0;

            retval = select(maxfd+1,&rfds,NULL,NULL,&tv);
            if(retval < 0)
            {
                printf("select error!%s\n",strerror(errno));
                break;
            }
            else if(retval == 0)
            {
                continue;
            }
            else
            {
                if(FD_ISSET(new_fd,&rfds))/* Determine whether the state of the FD in the fdset collection is changing. */
                {
                    /* If there is message, accept and display */
                    memset(&buf,0,sizeof(buf));
                    /* Receive messages sent from the other, up to MAX_BUFF bytes */
                    len = recv(new_fd,buf,MAX_BUFF,0);
                    if(len > 0)
                    {
                        printf("Receive message success: %s \n",buf);

                    }
                    else
                    {
                        if(len < 0)
                        {
                            printf("Receive message fail,error is %s.\n",errno,strerror(errno));

                        }
                        else
                            printf("quit\n");
                        break;
                    }
                }//FD_ISSET = Socket
                if(FD_ISSET(0,&rfds))
                {
                    memset(&buf,0,sizeof(buf));
                    read(0,buf,MAX_BUFF);

                    len = send(new_fd,buf,strlen(buf)-1,0);
                    if(len < 0)
                    {
                        printf("error!\n");
                        break;
                    }
                    else
                    {
                        printf("messages success!\n %s",buf);
                    }
                }//FD_ISSET = 0
            }
        }//End of second while
        close(new_fd);
    }//End of frist while
    close(sockfd);
    return 0;
} /* ----- End of main() ----- */

client.c

/*  Socket head file */
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>/*sockaddr_in{}*/
#include<arpa/inet.h>

/*  Unix standard head file */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>

#include <errno.h>/* strerror(),perror(),errno head file*/
#include <sys/time.h>
#include <sys/wait.h>

#define MAXBUFF 1024 
#define PORT 9999

/********************************************************************************
 *  Description:
 *   Input Args:
 *  Output Args:
 * Return Value:
 ********************************************************************************/
int main (int argc, char **argv)
{
    int sockfd;
    int len;
    int retval;
    int maxfd = -1;

    fd_set rfds;

    struct sockaddr_in dest;
    struct timeval tv;

    char buff[MAXBUFF];

    if(2 != argc)
    {
        printf("input error");
        return -1;
    }

    /* Use Socket() function */
    if((sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
    {
        perror("Socket error");
        exit(errno);
    }

    /*Initialize the address and port information of the server */
    memset(&dest,0,sizeof(dest));
    dest.sin_family = AF_INET;
    dest.sin_port = htons(PORT);

    if(inet_pton(AF_INET,argv[1],&dest.sin_addr)<=0)
    {
        perror("inet_pton() to set IP address failure");
        exit(1);
    }

    /* connect to server */
    printf("Connect to server[%s:%d]\n",argv[1],PORT);
    if(connect(sockfd,(struct sockaddr *)&dest,sizeof(dest))<0)
    {
        perror("connect error");
        exit(errno);
    }

    printf("\nReady to chatting...\n");
    while(1)
    {
         /*  Set empty */
        FD_ZERO(&rfds);
        /*  Add the standard input handle 0 */
        FD_SET(0,&rfds);
         maxfd = 0;
        /* Add the current connection handle new_fd */
         FD_SET(sockfd,&rfds);
         if(sockfd > maxfd)
         {
             maxfd = sockfd;
         }
        /*  Set maximum waiting time */
         tv.tv_sec = 1;
         tv.tv_usec = 0;
        /* Start to wait */
         retval = select(maxfd + 1,&rfds,NULL,NULL,&tv);
         if(retval < 0)
         {
             printf("select error\n");
             break;
         }
         else if(retval == 0)
         {
            continue;
         }
         else
         {
             if(FD_ISSET(sockfd,&rfds))/* Determine whether the state of the FD in the fdset collection is changing. */
             {
                memset(&buff,0,sizeof(buff));
                /* Receive messages sent from the other, up to MAX_BUFF bytes */
                len = recv(sockfd,buff,MAXBUFF,0);
                if(len > 0)
                {
                    printf("Receive messages success: %s \n",buff);

                }
                else
                {
                    if(len < 0)
                    {
                        printf("Receive messages fail,error is:%s.\n",errno,strerror(errno));
                    }
                    else
                        printf("quit\n");
                    break;
                }
             }//FD_ISSET = sockfd
             if(FD_ISSET(0,&rfds))
             {
                memset(&buff,0,sizeof(buff));
                read(0,buff,MAXBUFF);

                len = send(sockfd,buff,strlen(buff)-1,0);
                if(len < 0)
                {
                    printf("Send error\n");
                    break;
                }
                else
                {
                    printf("Send messages success!\n %s...\n",buff);
                }
             }//FD_ISSET = 0
         }//select finished

    }//End of while
    close(sockfd);
    return 0;
} /* ----- End of main() ----- */

其中在client.c使用了select()函数。
测试结果:
这里写图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值