zoukankan      html  css  js  c++  java
  • 网络编程基础之TCP学习(二)编程案例

    TCP网络编程流程如下:

    实现功能:服务器端与客户端成功通讯后返回get!

    服务器端程序

      1 #include <netdb.h>
      2 #include <sys/socket.h>
      3 #include <unistd.h>
      4 #include <string.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <memory.h>
      8 #include <signal.h>
      9 #include <arpa/inet.h>
     10 
     11 int sockfd;
     12 
     13 void sig_handler(int signo)
     14 {
     15     if(signo == SIGINT)
     16     {
     17         printf("server close
    ");
     18         /*步骤6:关闭socket*/
     19         close(sockfd);
     20         exit(1);
     21     }
     22 }
     23 
     24 /*输出连接上来的客户端相关信息*/
     25 void out_addr(struct sockaddr_in *clientaddr)
     26 {
     27     //将端口从网络字节序转换成主机字节序
     28     int port = ntohs(clientaddr->sin_port);
     29     char ip[16];
     30     memset(ip, 0, sizeof(ip));
     31     //将ip地址从网络字节序转换成点分十进制
     32     inet_ntop(AF_INET,
     33             &clientaddr->sin_addr.s_addr, ip, sizeof(ip));
     34     printf("client:%s(%d) connected
    ", ip, port);
     35 }
     36 
     37 void do_server(int fd)
     38 {
     39 
     40     //返回get!
     41     char t[20] = "get!";
     42     char *s = t;
     43     size_t size = (strlen(s)+1)*sizeof(char);
     44     t[size-1] = '
    ';
     45     //将服务器获得的系统时间写回到客户端
     46     if(write(fd, s, size) != size)
     47     {
     48         perror("write error");
     49     }
     50 
     51 }
     52 
     53 int main(int argc, char *argv[])
     54 {
     55     if(argc < 2)
     56     {
     57         printf("usage: %s #port
    ",argv[0]);
     58         exit(1);
     59     }
     60     if(signal(SIGINT, sig_handler) == SIG_ERR)
     61     {
     62         perror("signal sigint error");
     63         exit(1);
     64     }
     65     
     66     /* 步骤1: 创建socket(套接字)
     67      * AF_INET:IPV4
     68      * SOCK_STREAM:TCP协议
     69      **/
     70     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     71     if(sockfd < 0)
     72     {
     73         perror("socket error");
     74         exit(1);
     75     }
     76     /* 步骤2:调用bind函数将socket和地址
     77      * (包括ip、port)进行绑定
     78      */
     79     struct sockaddr_in serveraddr;
     80     memset(&serveraddr, 0, sizeof(serveraddr));
     81     //往地址中填入ip、port、internet地址族类型
     82     serveraddr.sin_family = AF_INET;//IPV4
     83     serveraddr.sin_port = htons(atoi(argv[1]));
     84     serveraddr.sin_addr.s_addr = INADDR_ANY;
     85     //监听所有服务器上ip得到的连接请求
     86     // #define INADDR_ANY (uint32_t)0x00000000
     87     if(bind(sockfd,(struct sockaddr*)&serveraddr,
     88                 sizeof(serveraddr)) < 0)
     89     {
     90         perror("bind error");
     91         exit(1);
     92     }
     93 
     94     /*
     95      * 步骤3:调用listen函数启动监听(指定port监听)
     96      *          通知系统去接受来自客户端的连接请求
     97      *          (将接受到的客户端的连接请求放置到对应的队列中)
     98      × 第二个参数:指定队列的长度
     99      */
    100     if(listen(sockfd, 10) < 0)
    101     {
    102         perror("listen error");
    103         exit(1);
    104     }
    105 
    106     /*
    107      * 步骤4:调用accept函数从队列中获得
    108      *          一个客户端的请求连接,并返回新的
    109      * 注意:若没有客户端连接,调用此函数后会阻塞,
    110      *        直到获得一改客户端的链接。
    111      */
    112     struct sockaddr_in clientaddr;
    113     socklen_t clientaddr_len = sizeof(clientaddr);
    114     while(1)
    115     {
    116         int fd = accept(sockfd, 
    117                 (struct sockaddr*)&clientaddr,
    118                     &clientaddr_len);
    119         if(fd < 0)
    120         {
    121             perror("accept error");
    122             continue;
    123         }
    124     /*
    125      * 步骤5:调用I/O函数(read/write)和
    126      * 连接的刻苦端进行双向的通信
    127      */
    128         out_addr(&clientaddr);
    129         do_server(fd);
    130 
    131     /* 步骤6:关闭socket*/
    132         close(fd);
    133     }
    134     return 0;
    135 }

    客户端程序

    #include <netdb.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <memory.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    
    int main(int argc, char *argv[])
    {
    
        if(argc < 3)
        {
            printf("usage: %s ip port",argv[0]);
            exit(1);
        }
    
        /*步骤1:创建socket*/
        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if(sockfd < 0)
        {
            perror("socket error");
            exit(1);
        }
    
        struct sockaddr_in serveraddr;
        memset(&serveraddr, 0, sizeof(serveraddr));
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_port = htons(atoi(argv[2]));
        //将ipo地址转换成网络字节序后填入serveraddr中
        inet_pton(AF_INET,argv[1],
                &serveraddr.sin_addr.s_addr);
    
        /*
         * 步骤2:客户端调用connect函数连接到服务器端
         */
        if(connect(sockfd,
                    (struct sockaddr*)&serveraddr,
                        sizeof(serveraddr)) < 0)
        {
            perror("connect error");
            exit(1);
        }
    
        /*步骤3:调用IO函数和服务器端进行双向通信*/
        char buffer[1024];
        memset(buffer, 0, sizeof(buffer));
        size_t size;
        if((size = read(sockfd,
                        buffer,sizeof(buffer))) < 0)
        {
            perror("read error");
        }
        if(write(STDOUT_FILENO, buffer, size) != size)
        {
            perror("write error");
        }
    
    
        return 0;
    }

  • 相关阅读:
    Java子类与父类的初始化
    悠哈牛奶糖为什么有五种味道单独装的,而不是混合装的
    C++ TinyXml操作(含源码下载)
    动物园海洋馆
    冰上行走
    Tmux : GNU Screen 的替代品
    考虑使用jruby
    关于一些展现的框架
    python抓取google搜索url
    pythonwebkit
  • 原文地址:https://www.cnblogs.com/lttdxuexizhilu/p/11604358.html
Copyright © 2011-2022 走看看