服务器端: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. Python之路【第五篇】: 函数、闭包、装饰器、迭代器、生成器

    目录 函数补充进阶 函数对象 函数的嵌套 名称空间与作用域 闭包函数 函数之装饰器 函数之可迭代对象 函数之迭代器 函数之生成器 面向过程的程序设计思想 一.函数进阶之函数对象 1. 函数对象 秉承着 ...

  2. shell 从变量中切割字符串

    1. 在shell变量中切割字符串 shell中截取字符串的方法有很多中,${expression}一共有9种使用方法.${parameter:-word}${parameter:=word}${pa ...

  3. oracle date 看时间

    SELECT to_char(DATE_TIME,'yyyy-MM-dd HH24:mi:ss') FROM AUDIT_EVENT;

  4. 【BZOJ 4148】 4148: [AMPPZ2014]Pillars (乱搞)

    4148: [AMPPZ2014]Pillars Time Limit: 5 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 100  Solve ...

  5. 【BZOJ 2440】 2440: [中山市选2011]完全平方数 (二分+容斥原理+莫比乌斯函数)

    2440: [中山市选2011]完全平方数 Description 小 X 自幼就很喜欢数.但奇怪的是,他十分讨厌完全平方数.他觉得这些数看起来很令人难受.由此,他也讨厌所有是完全平方数的正整数倍的数 ...

  6. [BZOJ4887][TJOI2017]可乐(DP+矩阵快速幂)

    题目描述 加里敦星球的人们特别喜欢喝可乐.因而,他们的敌对星球研发出了一个可乐机器人,并且放在了加里敦星球的1号城市上.这个可乐机器人有三种行为: 停在原地,去下一个相邻的城市,自爆.它每一秒都会随机 ...

  7. 【坐标变换】【二维偏序】【线段树】Gym - 100820G - Racing Gems

    题意:第一象限有n个点,你从x正半轴任选一个位置出发,vy恒定,vx可以任意变化,不过只能在-vy/r到vy/r之间变化,问你最多能经过多少个点. 暴力dp是n^2,不可取. 注意到,一个点,所能到达 ...

  8. tarjan算法+缩点--cojs 908. 校园网

    cojs 908. 校园网 ★★   输入文件:schlnet.in   输出文件:schlnet.out   简单对比时间限制:1 s   内存限制:128 MB USACO/schlnet(译 b ...

  9. ThinkPHP -- 基础入门

      ThinkPHP文件结构说明: |——ThinkPHP.php    框架入口文件    |——Common            框架公共文件目录    |——Conf              ...

  10. Unity创建asset文件的扩展编辑器

    using UnityEngine; using UnityEditor; using System.IO; public class CreateAsset : EditorWindow { pri ...