zoukankan      html  css  js  c++  java
  • linux网络编程:用C语言实现的聊天程序(同步通信)

    http://blog.chinaunix.net/space.php?uid=8196371&do=blog&id=1641031

    通过TCP协议,用C语言实现的同步聊天程序,注释写的比较详细,个人觉得对字符串处理比较充分,能够正常编译运行,拿出来和大家分享一下!

    1、客户端源代码:

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

    #define BUFLEN 10

    int main(int argc, char **argv)
    {
        int sockfd;
        struct sockaddr_in s_addr;
        socklen_t len;
        unsigned int port;
        char buf[BUFLEN];    
        
        /*建立socket*/
        if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
            perror("socket");
            exit(errno);
        }else
            printf("socket create success! ");

        /*设置服务器端口*/    
        if(argv[2])
            port = atoi(argv[2]);
        else
            port = 4567;
        /*设置服务器ip*/
        bzero(&s_addr, sizeof(s_addr));
        s_addr.sin_family = AF_INET;
        s_addr.sin_port = htons(port);
        if (inet_aton(argv[1], (struct in_addr *)&s_addr.sin_addr.s_addr) == 0) {
            perror(argv[1]);
            exit(errno);
        }
        /*开始连接服务器*/    
        if(connect(sockfd,(struct sockaddr*)&s_addr,sizeof(struct sockaddr)) == -1){
            perror("connect");
            exit(errno);
        }else
            printf("conncet success! ");
        
        while(1){
            /******接收消息*******/
            bzero(buf,BUFLEN);
            len = recv(sockfd,buf,BUFLEN,0);
            if(len > 0)
                printf("服务器发来的消息是:%s,共有字节数是: %d ",buf,len);
            else{
                if(len < 0 )
                    printf("接受消息失败! ");
                else
                    printf("服务器退出了,聊天终止! ");
                break;    
            }
        _retry:    
            /******发送消息*******/    
            bzero(buf,BUFLEN);
            printf("请输入发送给对方的消息:");
            /*fgets函数:从流中读取BUFLEN-1个字符*/
            fgets(buf,BUFLEN,stdin);
            /*打印发送的消息*/
            //fputs(buf,stdout);
            if(!strncasecmp(buf,"quit",4)){
                printf("client 请求终止聊天! ");
                break;
            }
            /*如果输入的字符串只有" ",即回车,那么请重新输入*/
            if(!strncmp(buf," ",1)){
                printf("输入的字符只有回车,这个是不正确的!!! ");
                goto _retry;
            }
            /*如果buf中含有'n',那么要用strlen(buf)-1,去掉'n'*/    
            if(strchr(buf,'n'))
                len = send(sockfd,buf,strlen(buf)-1,0);
            /*如果buf中没有'n',则用buf的真正长度strlen(buf)*/    
            else
                len = send(sockfd,buf,strlen(buf),0);
            if(len > 0)
                printf("消息发送成功,本次共发送的字节数是:%d ",len);            
            else{
                printf("消息发送失败! ");
                break;            
            }
        }
        /*关闭连接*/
        close(sockfd);

        return 0;
    }

    2、服务器源代码:

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <string.h>
    4. #include <errno.h>
    5. #include <sys/socket.h>
    6. #include <arpa/inet.h>
    7. #include <netinet/in.h>
    8. #include <sys/types.h>
    9. #include <unistd.h>

    10. #define BUFLEN 10

    11. int main(int argc, char **argv)
    12. {
    13.     int sockfd, newfd;
    14.     struct sockaddr_in s_addr, c_addr;
    15.     char buf[BUFLEN];
    16.     socklen_t len;
    17.     unsigned int port, listnum;
    18.     
    19.     /*建立socket*/
    20.     if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
    21.         perror("socket");
    22.         exit(errno);
    23.     }else
    24.         printf("socket create success! ");
    25.     /*设置服务器端口*/    
    26.     if(argv[2])
    27.         port = atoi(argv[2]);
    28.     else
    29.         port = 4567;
    30.     /*设置侦听队列长度*/
    31.     if(argv[3])
    32.         listnum = atoi(argv[3]);
    33.     else
    34.         listnum = 3;
    35.     /*设置服务器ip*/
    36.     bzero(&s_addr, sizeof(s_addr));
    37.     s_addr.sin_family = AF_INET;
    38.     s_addr.sin_port = htons(port);
    39.     if(argv[1])
    40.         s_addr.sin_addr.s_addr = inet_addr(argv[1]);
    41.     else
    42.         s_addr.sin_addr.s_addr = INADDR_ANY;
    43.     /*把地址和端口帮定到套接字上*/
    44.     if((bind(sockfd, (struct sockaddr*) &s_addr,sizeof(struct sockaddr))) == -1){
    45.         perror("bind");
    46.         exit(errno);
    47.     }else
    48.         printf("bind success! ");
    49.     /*侦听本地端口*/
    50.     if(listen(sockfd,listnum) == -1){
    51.         perror("listen");
    52.         exit(errno);    
    53.     }else
    54.         printf("the server is listening! ");
    55.     while(1){
    56.         printf("*****************聊天开始*************** ");
    57.         len = sizeof(struct sockaddr);
    58.         if((newfd = accept(sockfd,(struct sockaddr*) &c_addr, &len)) == -1){
    59.             perror("accept");        
    60.             exit(errno);
    61.         }else
    62.             printf("正在与您聊天的客户端是:%s: %d ",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));
    63.         while(1){
    64.         _retry:
    65.             /******发送消息*******/
    66.             bzero(buf,BUFLEN);
    67.             printf("请输入发送给对方的消息:");
    68.             /*fgets函数:从流中读取BUFLEN-1个字符*/
    69.             fgets(buf,BUFLEN,stdin);
    70.             /*打印发送的消息*/
    71.             //fputs(buf,stdout);
    72.             if(!strncasecmp(buf,"quit",4)){
    73.                 printf("server 请求终止聊天! ");
    74.                 break;
    75.             }
    76.             /*如果输入的字符串只有" ",即回车,那么请重新输入*/
    77.             if(!strncmp(buf," ",1)){
    78.                 printf("输入的字符只有回车,这个是不正确的!!! ");
    79.                 goto _retry;
    80.             }    
    81.             /*如果buf中含有'n',那么要用strlen(buf)-1,去掉'n'*/            
    82.             if(strchr(buf,'n'))
    83.                 len = send(newfd,buf,strlen(buf)-1,0);
    84.             /*如果buf中没有'n',则用buf的真正长度strlen(buf)*/    
    85.             else
    86.                 len = send(newfd,buf,strlen(buf),0);
    87.             if(len > 0)
    88.                 printf("消息发送成功,本次共发送的字节数是:%d ",len);            
    89.             else{
    90.                 printf("消息发送失败! ");
    91.                 break;            
    92.             }
    93.             /******接收消息*******/
    94.             bzero(buf,BUFLEN);
    95.             len = recv(newfd,buf,BUFLEN,0);
    96.             if(len > 0)
    97.                 printf("客户端发来的信息是:%s,共有字节数是: %d ",buf,len);
    98.             else{
    99.                 if(len < 0 )
    100.                     printf("接受消息失败! ");
    101.                 else
    102.                     printf("客户端退出了,聊天终止! ");
    103.                 break;        
    104.             }
    105.         }
    106.         /*关闭聊天的套接字*/
    107.         close(newfd);
    108.         /*是否退出服务器*/
    109.         printf("服务器是否退出程序:y->是;n->否? ");
    110.         bzero(buf, BUFLEN);
    111.         fgets(buf,BUFLEN, stdin);
    112.         if(!strncasecmp(buf,"y",1)){
    113.             printf("server 退出! ");
    114.             break;
    115.         }
    116.     }
    117.     /*关闭服务器的套接字*/
    118.     close(sockfd);
    119.     return 0;
    120. }

    3、编译源代码:
    new@new-desktop:~/linux/c$ gcc -Wall sync-client.c -o sync-client
    new@new-desktop:~/linux/c$ gcc -Wall sync-server.c -o sync-server

    4、运行服务器程序:
    new@new-desktop:~/linux/c$ ./sync-server 127.0.0.1 4567
    socket create success!
    bind success!
    the server is listening!
    *****************聊天开始***************
    正在与您聊天的客户端是:127.0.0.1: 48639
    请输入发送给对方的消息:client
    消息发送成功,本次共发送的字节数是:6
    客户端发来的信息是:server,共有字节数是: 6
    请输入发送给对方的消息:

    5、运行客户端程序:
    new@new-desktop:~/linux/c$ ./sync-client 127.0.0.1 4567
    socket create success!
    conncet success!
    服务器发来的消息是:client,共有字节数是: 6
    请输入发送给对方的消息:server
    消息发送成功,本次共发送的字节数是:6

    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
    阅读(902) | 评论(0) | 转发(6) |
    给主人留下些什么吧!~~
    评论热议
  • 相关阅读:
    快照原理及场景
    CEP实时分析模型
    请求响应模式
    JMS消息服务模型
    EMF与GEF
    基于SOA的编程模型
    实时计算CEP
    数据库常见的场景
    自签证书服务加入证书验证
    post提交主订单数据(gateway)实现httpapi
  • 原文地址:https://www.cnblogs.com/ztguang/p/12647391.html
Copyright © 2011-2022 走看看