服务器端:server.c

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#include <unistd.h>

#include <arpa/inet.h>

#include <sys/time.h>

#include <sys/types.h>



#define MAXBUF 1024



int main(int argc, char **argv)

{

        int sockfd, new_fd;

        socklen_t len;

        struct sockaddr_in my_addr, their_addr;

        unsigned int myport, lisnum;

        char buf[MAXBUF + 1];

        fd_set rfds;

        struct timeval tv;

        int retval, maxfd = -1;



        if (argv[2])

                myport = atoi(argv[2]);       /* 将命令行字符串转换为整数。用于端口 */

        else

                myport = 8888;                           /* 设置默认端口 */

        if (argv[3])

                lisnum = atoi(argv[3]);                     /* 监听队列大小 */

        else

                lisnum = 2;

        if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {             /* 创建socket对象 */

                perror("socket");

                exit(EXIT_FAILURE);

        }



        bzero(&my_addr, sizeof(my_addr));

        my_addr.sin_family = PF_INET;                /* 地址协议 */

        my_addr.sin_port = htons(myport);             /* 地址端口 */

        if (argv[1])

            my_addr.sin_addr.s_addr = inet_addr(argv[1]);

        else

            my_addr.sin_addr.s_addr = INADDR_ANY;                    /* 否则默认本机随意地址 */

        if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1) { /* 绑定地址信息 */

           perror("bind");

           exit(EXIT_FAILURE);

        }

         if (listen(sockfd, lisnum) == -1) { 
/* 监听网络 ,最大队列数是lisnum*/

            perror("listen");

            exit(EXIT_FAILURE);

         }



         while (1) 

{

            printf ("\n----wait for new connect\n");

                len = sizeof(struct sockaddr);

if ((new_fd =accept(sockfd, (struct sockaddr *) &their_addr,&len)) == -1) {

/* 堵塞等待连接。连接成功返回新的socket描写叙述符,their_addr存储client的sockaddr 地址信息

            perror("accept");

              exit(errno);

            } else

            printf("server: got connection from %s, port %d, socket %d\n", 

inet_ntoa(their_addr.sin_addr),ntohs(their_addr.sin_port), new_fd);

            while (1) 

{

              FD_ZERO(&rfds);    
/* 清零rfds集合 */

                FD_SET(0, &rfds);  
/* 把标准输入加入rfds集合 */

                FD_SET(new_fd, &rfds);                 /*
把new_fd加入rfds集合 */

                maxfd = new_fd;

                tv.tv_sec = 1;

                tv.tv_usec = 0;

                retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);    /*
maxfd + 1监听的最大值加一 */

                if (retval == -1) 

{

perror("select");

exit(EXIT_FAILURE);

} else if (retval == 0) {

                  continue;

                } 

else

{

                    if (FD_ISSET(0, &rfds))                        /* 假设是标准输入可读 */

{

                          bzero(buf, MAXBUF + 1);

                        fgets(buf, MAXBUF, stdin);

                          if (!strncasecmp(buf, "quit", 4)) {

                            printf("i will quit!\n");

                              break;

                          }

                          len = send(new_fd, buf, strlen(buf) - 1, 0);

                        if (len > 0)

                                printf ("send successful,%d byte send!\n",len);

                          else {

                              printf("send failure!");

                            break;

                            }

}

                    if (FD_ISSET(new_fd, &rfds))             /* 假设是new_fd可读 */



                            bzero(buf, MAXBUF + 1);

                          len = recv(new_fd, buf, MAXBUF, 0);

                            if (len > 0)

                                printf ("recv success :'%s',%dbyte recv\n", buf, len);

                            else

{

                              if (len < 0)

                                printf("recv failure\n");

                                else

{

                                  printf("the ohter one end ,quit\n");

                                  break;

}

                            }

            }

                 }

}

            close(new_fd);

            printf("need othe connecdt (no->quit)");

            fflush(stdout);

            bzero(buf, MAXBUF + 1);

            fgets(buf, MAXBUF, stdin);

            if (!strncasecmp(buf, "no", 2)) 

{

                printf("quit!\n");

                break;

            }

        }

        close(sockfd);

        return 0;

}



客户端程序:client.c

#include <stdio.h>

#include <string.h>

#include <errno.h>

#include <sys/socket.h>

#include <resolv.h>

#include <stdlib.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <unistd.h>

#include <sys/time.h>

#include <sys/types.h>



#define MAXBUF 1024

int main(int argc, char **argv)

{

    int sockfd, len;

    struct sockaddr_in dest;

    char buffer[MAXBUF + 1];

    fd_set rfds;

    struct timeval tv;

    int retval, maxfd = -1;



    if (argc != 3) 

    {

        printf("argv format errno,pls:\n\t\t%s IP port\n",argv[0], argv[0]);

        exit(EXIT_FAILURE);

    }

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 

    {

        perror("Socket");

        exit(EXIT_FAILURE);

    }

    bzero(&dest, sizeof(dest));

    dest.sin_family = AF_INET;

    dest.sin_port = htons(atoi(argv[2]));

    if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) 

    {

        perror(argv[1]);

        exit(EXIT_FAILURE);

    }



    if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) 

    {

        perror("Connect ");

        exit(EXIT_FAILURE);

    }



    printf("\nget ready pls chat\n");

    while (1) 

{

        FD_ZERO(&rfds);

        FD_SET(0, &rfds);

        FD_SET(sockfd, &rfds);

        maxfd = sockfd;

        tv.tv_sec = 1;

        tv.tv_usec = 0;

        retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);

        if (retval == -1) 

{

            printf("select %s", strerror(errno));

            break;

        } 

else if (retval == 0)

            continue;

else

{

            if (FD_ISSET(sockfd, &rfds)) 

{

                bzero(buffer, MAXBUF + 1);

                len = recv(sockfd, buffer, MAXBUF, 0);

                if (len > 0)

                    printf ("recv message:'%s',%d byte recv\n",buffer, len);

                else 

{

                    if (len < 0)

                        printf ("message recv failure\n");

                    else

{

                        printf("the othe quit ,quit\n");

                    break;

}

                }

            }

            if (FD_ISSET(0, &rfds)) 

{

                bzero(buffer, MAXBUF + 1);

                fgets(buffer, MAXBUF, stdin);

                if (!strncasecmp(buffer, "quit", 4)) {

                    printf("i will quit\n");

                    break;

                }

                len = send(sockfd, buffer, strlen(buffer) - 1, 0);

                if (len < 0) {

                    printf ("message send failure");

                    break;

                } else

                    printf

                        ("send success,%d byte send\n",len);

            }

        }

    }

    close(sockfd);

    return 0;

}

測试方法例如以下:

gcc server.c -o server

gcc client.c -o client

./server 172.16.148.114  8888       /* 一个终端下。172.16.148.114是我虚拟机的IP地址*/

./client 172.16.148.114  8888      /*另外 一个终端下 */



select函数不会使用的參考这篇文章:http://blog.csdn.net/qq_21792169/article/details/50450360

Linux网络编程之聊天程序(TCP协议之select)的更多相关文章

  1. 网络编程应用:基于TCP协议【实现一个聊天程序】

    要求: 基于TCP协议实现一个聊天程序,客户端发送一条数据,服务器端发送一条数据 客户端代码: package Homework1; import java.io.IOException; impor ...

  2. Linux网络编程——连接和面向连接的协议之间没有区别

    网络编程中最重要的概念就是连接取向(connection-oriented)和无连接(connectionless)协议.虽然本质.两者之间的区别是不难理解,编程的人来说,却是个非常easy混淆的问题 ...

  3. Java网络编程——UDP聊天程序

    UDP简介 UDP协议的全称是用户数据报,在网络中它与TCP协议一样用于处理数据报.在OSI模型中,UDP位于第四层--传输层,处于IP协议额上一层.UDP有不提供数据报分组.组装以及不能对数据报排序 ...

  4. UNIX/Linux网络编程基础:图解TCP/IP协议栈

    目录 1.主机到网络层协议:以太网协议 2.IP协议 3.网际控制报文协议(ICMP) 4.传输控制协议(TCP) 5.用户数据报文协议(UDP) 6.流控制传输协议(SCTP) 7.地址解析协议(A ...

  5. 网络编程(二)--TCP协议、基于tcp协议的套接字socket

    一.TCP协议(Transmission Control Protocol 传输控制协议) 1.可靠传输,TCP数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据包的长度不会 ...

  6. python网络编程——使用UDP、TCP协议收发信息

    UDP UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送. UDP传输数据时有大小限制,每个被传输的数据报必须限定在64KB之内. UDP ...

  7. 网络编程(二)——TCP协议、基于tcp协议的套接字socket

    TCP协议与基于tcp协议的套接字socket 一.TCP协议(流式协议) 1.可靠传输,TCP数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据包的长度不会超过IP数据包的 ...

  8. 网络编程应用:基于TCP协议【实现对象传输】--练习

    要求: 基于TCP协议实现,客服端向服务器发送一个对象 服务器接受并显示用户信息 ,同时返回给客户端 "数据已收到" 建一个Student类,属性:name age Student ...

  9. 网络编程应用:基于TCP协议【实现文件上传】--练习

    要求: 基于TCP协议实现一个向服务器端上传文件的功能 客户端代码: package Homework2; import java.io.File; import java.io.FileInputS ...

随机推荐

  1. axio post 请求后端接收不到参数的解决办法

    原因是没有对参数进行序列化 默认情况下,axios将JavaScript对象序列化为JSON. 要以应用程序/ x-www-form-urlencoded格式发送数据. 在拦截器前修改 方法一,用原生 ...

  2. luoguP4320 道路相遇 圆方树

    标题已经告诉你怎么做了..... 两点间的圆点个数即为所求 建出圆方树后打个树剖求$lca$就行..... 复杂度$O(n + q \log n)$ #include <cstdio> # ...

  3. 数位dp小结以及模板

    这里是网址 别人的高一啊QAQ.... 嗯一般记忆化搜索是比递推好写的所以我写的都是dfs嗯......(因为我找不到规律啊摔,还是太菜.....) 显然这个东西的条件是非常的有套路..但是不管怎么样 ...

  4. 【四边形不等式】noi95- 合并石子

    [题目大意] 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分.试设计出1个算法,计算出将N堆石子合并成 ...

  5. [CC-STREETTA]The Street

    [CC-STREETTA]The Street 题目大意: 给定两个长度为\(n(n\le10^9)\)的数列\(A\)和\(B\),开始数列\(A\)中每一项值为\(-\infty\),数列\(B\ ...

  6. Dubbo整合SpringCloud图片显示问题

    Dubbo整合SpringCloud图片显示问题 Tips:公司项目,记录一点经验吧,理解的不对的地方欢迎大神指点 问题:商品图片上传功能(公司没有专门文件服务器)写的保存目录直接是保存在docker ...

  7. BZOJ 1040 ZJOI 2008 骑士 树形DP

    题意: 有一些战士,他们有战斗力和讨厌的人,选择一些战士,使他们互不讨厌,且战斗力最大,范围1e6 分析: 把战士看作点,讨厌的关系看作一条边,连出来的是一个基环树森林. 对于一棵基环树,我们找出环, ...

  8. python开发_类型转换convert

    在python的开发过程中,难免会遇到类型转换,这里给出常见的类型转换demo: int(x [,base ]) 将x转换为一个整数 long(x [,base ]) 将x转换为一个长整数 float ...

  9. VMware中网络设置之host-only

    有了前面一篇的NAT的网络设置,本文就显得非常简单了.同样图文结合的步骤: 1.设置host-only模式. 2.设置linux虚拟机的静态IP.进入linux系统,点击主菜单---系统设置---网络 ...

  10. NFC TI TRF7970A Breakout Board for BusPirate or other HW

    http://dangerousprototypes.com/forum/viewtopic.php?f=19&t=3187 Just a news about a new Hardware ...