zoukankan      html  css  js  c++  java
  • Linux环境下服务器和客户端的网络通信

      UNIX系统中的网络协议是这样分层的:1.应用层(telnet,ftp等);2.主机到主机传输层(TCP,UDP);3.Internet层(IP和路由);4.网络访问层(网络,数据链路,物理层)。
      套接口描述符使用 sockaddr_in 数据结构,有了套接口之后需要调用bind()函数把套接口绑定到本地计算机的一个接口上,使用inet_addr()函数将普遍形式的IP地址转化为无符号的整型数,调用socket()函数获得文件描述符。程序分为客户端和服务端。应用select函数来实现异步的读写操作。在服务器端:首先先创建套接字,然后绑定,接下进入一个无限循环,用accept函数,接受“连接”请求,然后调用创建线程函数,创造新的线程,进入下一个循环。这样每当有一个新的“连接”被接受都会创建一个新的线程。

    服务器端程序如下:

    //server.c

    View Code
      1 //server.c
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <errno.h>
      5 #include <string.h>
      6 #include <sys/types.h>
      7 #include <netinet/in.h>
      8 #include <sys/socket.h>
      9 #include <sys/wait.h>
     10 #include <unistd.h>
     11 #include <arpa/inet.h>
     12 #include <sys/time.h>
     13 #include <sys/types.h>
     14 
     15 #define MAXBUF 1024
     16 
     17 
     18 int main(int argc, char **argv)
     19 {
     20     int sockfd, new_fd;
     21     socklen_t len;
     22     struct sockaddr_in my_addr, their_addr;
     23     unsigned int myport, lisnum;
     24     char buf[MAXBUF + 1];
     25     fd_set rfds;
     26     struct timeval tv;
     27     int retval, maxfd = -1;
     28 
     29     if (argv[1])
     30         myport = atoi(argv[1]);
     31     else
     32         myport = 7838;
     33 
     34     if (argv[2])
     35         lisnum = atoi(argv[2]);
     36     else
     37         lisnum = 2;
     38 
     39     if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) 
     40    {
     41         perror("socket");
     42         exit(1);
     43     }
     44 
     45     bzero(&my_addr, sizeof(my_addr));
     46     my_addr.sin_family = PF_INET;
     47     my_addr.sin_port = htons(myport);
     48     if (argv[3])
     49         my_addr.sin_addr.s_addr = inet_addr(argv[3]);
     50     else
     51         my_addr.sin_addr.s_addr = INADDR_ANY;
     52 
     53     if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))
     54         == -1) {
     55         perror("bind");
     56         exit(1);
     57     }
     58 
     59     if (listen(sockfd, lisnum) == -1) {
     60         perror("listen");
     61         exit(1);
     62     }
     63 
     64     while (1) {
     65         printf
     66             (" ----等待新的连接到来开始新的聊天…… ");
     67         len = sizeof(struct sockaddr);
     68         if ((new_fd =
     69              accept(sockfd, (struct sockaddr *) &their_addr,
     70                     &len)) == -1) {
     71             perror("accept");
     72             exit(errno);
     73         } else
     74             printf("server: got connection from %s, port %d, socket %d ",
     75                    inet_ntoa(their_addr.sin_addr),
     76                    ntohs(their_addr.sin_port), new_fd);
     77 
     78         /* 开始处理每个新连接上的数据收发 */
     79         printf
     80      (" 准备就绪,可以开始聊天了……输入消息回车即可发信息给对方 ");
     81         while (1) {
     82             /* 把集合清空 */
     83             FD_ZERO(&rfds);
     84             /* 把标准输入句柄0加入到集合中 */
     85             FD_SET(0, &rfds);
     86             maxfd = 0;
     87             /* 把当前连接句柄new_fd加入到集合中 */
     88             FD_SET(new_fd, &rfds);
     89             if (new_fd > maxfd)
     90                 maxfd = new_fd;
     91             /* 设置最大等待时间 */
     92             tv.tv_sec = 1;
     93             tv.tv_usec = 0;
     94             /* 开始等待 */
     95             retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);
     96             if (retval == -1) {
     97                 printf("将退出,select出错! %s", strerror(errno));
     98                 break;
     99             } else if (retval == 0) {
    100                 /* printf
    101               ("没有任何消息到来,用户也没有按键,继续等待…… "); */
    102                 continue;
    103             } else {
    104                 if (FD_ISSET(0, &rfds)) {
    105                     /* 用户按键了,则读取用户输入的内容发送出去 */
    106                     bzero(buf, MAXBUF + 1);
    107                     fgets(buf, MAXBUF, stdin);
    108                     if (!strncasecmp(buf, "quit", 4)) {
    109                         printf("自己请求终止聊天! ");
    110                         break;
    111                     }
    112                     len = send(new_fd, buf, strlen(buf) - 1, 0);
    113                     if (len > 0)
    114                         printf
    115                       ("消息:%s 发送成功,共发送了%d个字节! ",
    116                              buf, len);
    117                     else {
    118                         printf
    119                  ("消息'%s'发送失败!错误代码是%d,错误信息是'%s' ",
    120                              buf, errno, strerror(errno));
    121                         break;
    122                     }
    123                 }
    124                 if (FD_ISSET(new_fd, &rfds)) {
    125      /* 当前连接的socket上有消息到来则接收对方发过来的消息并显示 */
    126                     bzero(buf, MAXBUF + 1);
    127                     /* 接收客户端的消息 */
    128                     len = recv(new_fd, buf, MAXBUF, 0);
    129                     if (len > 0)
    130                         printf
    131                       ("接收消息成功:'%s',共%d个字节的数据 ",
    132                              buf, len);
    133                     else {
    134                         if (len < 0)
    135                             printf
    136                    ("消息接收失败!错误代码是%d,错误信息是'%s' ",
    137                                  errno, strerror(errno));
    138                         else
    139                             printf("对方退出了,聊天终止 ");
    140                         break;
    141                     }
    142                 }
    143             }
    144         }
    145         close(new_fd);
    146         /* 处理每个新连接上的数据收发结束 */
    147         printf("还要和其它连接聊天吗?(no->退出)");
    148         fflush(stdout);
    149         bzero(buf, MAXBUF + 1);
    150         fgets(buf, MAXBUF, stdin);
    151         if (!strncasecmp(buf, "no", 2)) {
    152             printf("终止聊天! ");
    153             break;
    154         }
    155     }
    156 
    157     close(sockfd);
    158     return 0;
    159 }

    客户端程序如下:

    //client.c

    View Code
      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <errno.h>
      4 #include <sys/socket.h>
      5 #include <resolv.h>
      6 #include <stdlib.h>
      7 #include <netinet/in.h>
      8 #include <arpa/inet.h>
      9 #include <unistd.h>
     10 #include <sys/time.h>
     11 #include <sys/types.h>
     12 
     13 #define MAXBUF 1024
     14 
     15 int main(int argc, char **argv)
     16 {
     17     int sockfd, len;
     18     struct sockaddr_in dest;
     19     char buffer[MAXBUF + 1];
     20     fd_set rfds;
     21     struct timeval tv;
     22     int retval, maxfd = -1;
     23 
     24     if (argc != 3) {
     25         printf
     26         ("参数错误!正确用法如下: %s IP地址 端口 比如: %s 127.0.0.1 80 此程序从某个IP地址的服务器某个端口接收最多MAXBUF个字节的消息",
     27              argv[0], argv[0]);
     28         exit(0);
     29     }
     30     /* 创建一个 socket 用于 tcp 通信 */
     31     if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
     32         perror("Socket");
     33         exit(errno);
     34     }
     35 
     36     /* 初始化服务器端(对方)的地址和端口信息 */
     37     bzero(&dest, sizeof(dest));
     38     dest.sin_family = AF_INET;
     39     dest.sin_port = htons(atoi(argv[2]));
     40     if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) {
     41         perror(argv[1]);
     42         exit(errno);
     43     }
     44 
     45     /* 连接服务器 */
     46     if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {
     47         perror("Connect ");
     48         exit(errno);
     49     }
     50 
     51     printf
     52    (" 准备就绪,可以开始聊天了……输入消息回车即可发信息给对方 ");
     53     while (1) {
     54         /* 把集合清空 */
     55         FD_ZERO(&rfds);
     56         /* 把标准输入句柄0加入到集合中 */
     57         FD_SET(0, &rfds);
     58         maxfd = 0;
     59         /* 把当前连接句柄sockfd加入到集合中 */
     60         FD_SET(sockfd, &rfds);
     61         if (sockfd > maxfd)
     62             maxfd = sockfd;
     63         /* 设置最大等待时间 */
     64         tv.tv_sec = 1;
     65         tv.tv_usec = 0;
     66         /* 开始等待 */
     67         retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);
     68         if (retval == -1) {
     69             printf("将退出,select出错! %s", strerror(errno));
     70             break;
     71         } else if (retval == 0) {
     72             /* printf
     73                ("没有任何消息到来,用户也没有按键,继续等待…… "); */
     74             continue;
     75         } else {
     76             if (FD_ISSET(sockfd, &rfds)) {
     77          /* 连接的socket上有消息到来则接收对方发过来的消息并显示 */
     78                 bzero(buffer, MAXBUF + 1);
     79               /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */
     80                 len = recv(sockfd, buffer, MAXBUF, 0);
     81                 if (len > 0)
     82                     printf
     83                         ("接收消息成功:'%s',共%d个字节的数据 ",
     84                          buffer, len);
     85                 else {
     86                     if (len < 0)
     87                         printf
     88                     ("消息接收失败!错误代码是%d,错误信息是'%s' ",
     89                              errno, strerror(errno));
     90                     else
     91                         printf("对方退出了,聊天终止! ");
     92                     break;
     93                 }
     94             }
     95             if (FD_ISSET(0, &rfds)) {
     96                 /* 用户按键了,则读取用户输入的内容发送出去 */
     97                 bzero(buffer, MAXBUF + 1);
     98                 fgets(buffer, MAXBUF, stdin);
     99                 if (!strncasecmp(buffer, "quit", 4)) {
    100                     printf("自己请求终止聊天! ");
    101                     break;
    102                 }
    103                 /* 发消息给服务器 */
    104                 len = send(sockfd, buffer, strlen(buffer) - 1, 0);
    105                 if (len < 0) {
    106                     printf
    107                  ("消息'%s'发送失败!错误代码是%d,错误信息是'%s' ",
    108                          buffer, errno, strerror(errno));
    109                     break;
    110                 } else
    111                     printf
    112                       ("消息:%s 发送成功,共发送了%d个字节! ",
    113                          buffer, len);
    114             }
    115         }
    116     }
    117     /* 关闭连接 */
    118     close(sockfd);
    119     return 0;
    120 }

    编译过程:gcc -Wall server.c -o server
             gcc -Wall client.c -o client

    运行:在一个终端里运行  ./server 3490 1  模拟服务器端,其中3490指本地接口
         在另一个终端运行  ./client 127.0.0.1 3490  模拟客户端,最后一个参数应与服务器定义的接口相同

  • 相关阅读:
    js原型链
    charles重放攻击2
    charles攻击重放测试网页
    js逆向基础知识
    js重放攻击
    js逆向之 中间人攻击-js注入
    修改jadx默认内存
    frida-ida hook操作
    关于ios 9系统完全越狱frida安装不上的的问题
    IDA 静态调试和动态调试
  • 原文地址:https://www.cnblogs.com/fanyabo/p/2551432.html
Copyright © 2011-2022 走看看