zoukankan      html  css  js  c++  java
  • Linux 网络编程一步一步学(六)客户/服务端通信

    CLIENT

        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 #define MAXBUF 1024
       11 int main(int argc, char **argv)
    -  12 {
    |  13     int sockfd, len;
    |  14     struct sockaddr_in dest;
    |  15     char buffer[MAXBUF + 1];
    -  16     if (argc != 3) {
    2  17         printf("参数格式错误!正确用法如下:\n\t\t%s IP 地址 端口\n\t比如:\t%s 127.0.0.1 80\n此程序用来从某个 IP 地址的服务器某个端口接收最多 MAXBUF 个字节的消息",argv[0], argv[0]);
    2  18         exit(0);
    2  19     }
    |  20     /* 创建一个 socket 用于 tcp 通信 */
    -  21     if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    2  22         perror("Socket");
    2  23         exit(errno);
    2  24     }
    |  25     printf("socket created\n");
    |  26     /* 初始化服务器端(对方)的地址和端口信息 */
    |  27     bzero(&dest, sizeof(dest));
    |  28     dest.sin_family = AF_INET;
    |  29     dest.sin_port = htons(atoi(argv[2]));
    -  30     if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) {
    2  31         perror(argv[1]);
    2  32         exit(errno);
    2  33     }
    |  34     printf("address created\n");
    |  35     /* 连接服务器 */
    -  36     if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {
    2  37         perror("Connect ");
    2  38         exit(errno);
    2  39     }
    |  40     printf("server connected\n");
    |  41     /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */
    |  42     bzero(buffer, MAXBUF + 1);
    |  43     /* 接收服务器来的消息 */
    |  44     len = recv(sockfd, buffer, MAXBUF, 0);
    |  45     if(len > 0) printf("接收消息成功:'%s',共%d个字节的数据\n", buffer, len);
    |  46     else printf("消息接收失败!错误代码是%d,错误信息是'%s'\n", errno, strerror(errno));
    |  47     bzero(buffer, MAXBUF + 1);
    |  48     strcpy(buffer, "这是客户端发给服务器端的消息\n");
    |  49     /* 发消息给服务器 */
    |  50     len = send(sockfd, buffer, strlen(buffer), 0);
    |  51     if(len < 0) printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n", buffer,errno, strerror(errno));
    |  52     else printf("消息'%s'发送成功,共发送了%d个字节!\n", buffer, len);
    |  53     /* 关闭连接 */
    |  54     close(sockfd);
    |  55     return 0;
    |  56 }
       57   

    SERVER

        1 #include <stdio.h>                                                                                           
        2 #include <stdlib.h>
        3 #include <errno.h>
        4 #include <string.h>
        5 #include <sys/types.h>
        6 #include <netinet/in.h>
        7 #include <sys/socket.h>
        8 #include <sys/wait.h>
        9 #include <unistd.h>
       10 #include <arpa/inet.h>
       11 #define MAXBUF 1024
       12 int main(int argc, char **argv)
    -  13 {
    |  14     int sockfd, new_fd;
    |  15     socklen_t len;
    |  16     struct sockaddr_in my_addr, their_addr;
    |  17     unsigned int myport, lisnum;
    |  18     char buf[MAXBUF + 1];
    |  19     if (argv[1])
    |  20         myport = atoi(argv[1]);
    |  21     else
    |  22         myport = 7838;
    |  23     if (argv[2])
    |  24         lisnum = atoi(argv[2]);
    |  25     else
    |  26         lisnum = 2;
    -  27     if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
    2  28         perror("socket");
    2  29         exit(1);
    2  30     }
    |  31     else printf("socket created\n");
    |  32 
    |  33     bzero(&my_addr, sizeof(my_addr));
    |  34     my_addr.sin_family = PF_INET;
    |  35     my_addr.sin_port = htons(myport);
    |  36     if(argv[3])
    |  37         my_addr.sin_addr.s_addr = inet_addr(argv[3]);
    |  38     else
    |  39         my_addr.sin_addr.s_addr = INADDR_ANY;
    |  40     if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1)
    -  41     {
    2  42         perror("bind");
    2  43         exit(1);
    2  44     }
    |  45     else printf("binded\n");
    -  46     if (listen(sockfd, lisnum) == -1) {
    2  47         perror("listen");
    2  48         exit(1);
    2  49     }
    |  50     else printf("begin listen\n");
    -  51     while(1) {
    2  52         len = sizeof(struct sockaddr);
    -  53         if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &len)) == -1) {
    3  54             perror("accept");
    3  55             exit(errno);
    3  56         }
    2  57         else
    2  58             printf("server: got connection from %s, port %d, socket%d\n",inet_ntoa(their_addr.sin_addr), ntohs(their_ad2dr.sin_port), new_fd);
    2  59         /* 开始处理每个新连接上的数据收发 */
    2  60         bzero(buf, MAXBUF + 1);
    2  61         strcpy(buf, "这是在连接建立成功后向客户端发送的第一个消息\n只能向new_fd这个用accept函数新建立的socket发消息,不能向sockfd这个监听socket发送消息,监听socket不能用来接收或发送消息\n");
    2  62         /* 发消息给客户端 */
    2  63         len = send(new_fd, buf, strlen(buf), 0);
    -  64         if(len < 0) {
    3  65             printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n", buf, errno,
    3  66             strerror(errno));
    3  67         }
    2  68         else printf("消息'%s'发送成功,共发送了%d个字节!\n", buf, len);
    2  69         bzero(buf, MAXBUF + 1);
    2  70         /* 接收客户端的消息 */
    2  71         len = recv(new_fd, buf, MAXBUF, 0);
    2  72         if(len > 0) printf("接收消息成功:'%s',共%d个字节的数据\n", buf, len);
    2  73         else printf("消息接收失败!错误代码是%d,错误信息是'%s'\n", errno, strerror(errno));
    2  74         /* 处理每个新连接上的数据收发结束 */
    2  75     }
    |  76     close(sockfd);
    |  77     return 0;
    |  78 }
       79    

    函数解释:

      accept():用来接受参数s 的socket 连线. 参数s 的socket 必需先经bind()、listen()函数处理过, 当有连线进来时accept()会返回一个新的socket 处理代码, 往后的数据传送与读取就是经由新的socket处理, 而原来参数s 的socket 能继续使用accept()来接受新的连线要求. 连线成功时, 参数addr 所指的结构会被系统填入远程主机的地址数据, 参数addrlen 为scokaddr 的结构长度. 关于机构sockaddr 的定义请参考bind().

      int accept(int s, struct sockaddr * addr, int * addrlen);
    函数说明:accept()用来接受参数s 的socket 连线. 参数s 的socket 必需先经bind()、listen()函数处理过, 当有连线进来时accept()会返回一个新的socket 处理代码, 往后的数据传送与读取就是经由新的socket处理, 而原来参数s 的socket 能继续使用accept()来接受新的连线要求. 连线成功时, 参数addr 所指的结构会被系统填入远程主机的地址数据, 参数addrlen 为scokaddr 的结构长度. 关于机构sockaddr 的定义请参考bind().

  • 相关阅读:
    颜色空间之CIE2000色差公式
    爱做梦的人-人的特性之一
    Lua文件操作和串行化
    Lua文件操作和串行化
    Lua调用C++带参数的方法
    Lua调用C++带参数的方法
    C++对Lua中table进行读取、修改和创建
    C++对Lua中table进行读取、修改和创建
    C++获取Lua全局变量和执行Lua多参数多返回值函数
    C++获取Lua全局变量和执行Lua多参数多返回值函数
  • 原文地址:https://www.cnblogs.com/liqiu/p/2981321.html
Copyright © 2011-2022 走看看