zoukankan      html  css  js  c++  java
  • 一对经典的时间获取客户/服务器程序

    前言

      本文通过一对经典的时间获取客户/服务器程序,展现了Linux网络编程的大体框架,为以后更深入的学习打下基础。

    客户服务器模式网络编程的大体框架

    客户端代码

     1 #include <stdio.h>
     2 // 下头文件包含socket(), bind()等套接字通信必须的函数。
     3 #include <sys/socket.h>
     4 // 下头文件包含网际套接字变量的类型定义等。
     5 #include <netinet/in.h>
     6 // 下头文件包含bzero()函数等
     7 #include <string.h>
     8 // 下头文件包含errno变量等
     9 #include <errno.h>
    10 
    11 #define MAXLINE 100 
    12 
    13 int main (int argc, char ** argv)
    14 {
    15     // 定义套接字描述符变量sockfd
    16     // 定义变量n存放read函数返回值
    17     int sockfd, n;
    18     // 定义字符数组recvline存放时间查询结果
    19     char recvline[MAXLINE + 1];
    20     // 定义套接字变量servaddr( 注意这里存放的是服务器端的信息 )
    21     struct sockaddr_in servaddr;
    22 
    23     // 检查命令格式是否正确
    24     if (argc != 2) {
    25         puts("命令格式错误
    ");
    26         return 1;
    27     }
    28     
    29     // 创建一个网际字节流套接字
    30     if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) <0) {
    31         puts("网际套接字创建失败
    ");
    32         return 2;
    33     }
    34 
    35     // 将套接字变量servaddr清零
    36     bzero(&servaddr, sizeof(servaddr));
    37     // 给套接字变量的协议段赋值( AF_INET表示IPv4协议 )
    38     servaddr.sin_family = AF_INET;
    39     // 给套接字变量的端口段赋值( 13是时间服务器端口 )
    40     servaddr.sin_port = htons(13);
    41     // 给套接字变量的IP段赋值( argv[1]存放服务器IP )
    42     if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
    43         puts("IP地址格式转换失败");
    44         return 3;
    45     }
    46 
    47     // 按照先前socket函数指定的协议类型与服务器进行连接
    48     if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
    49         puts("连接失败
    ");
    50         return 4;
    51     }
    52 
    53     // 从缓冲区读取时间查询结果并放进recvline数组中
    54     if ( (n = read(sockfd, recvline, MAXLINE)) > 0 ) {
    55         recvline[n] = 0;
    56         puts(recvline);
    57     }
    58     if (n < 0) {
    59         puts("读取数据发生错误");
    60     }
    61 
    62     return 0;
    63 }

    服务器端代码

     1 #include <stdio.h>
     2 
     3 // 下头文件包含socket(), bind()等套接字通信必须的函数。
     4 #include <sys/socket.h>
     5 // 下头文件包含网际套接字变量的类型定义等。
     6 #include <netinet/in.h>
     7 // 下头文件包含bzero()函数等
     8 #include <string.h>
     9 // 下头文件包含errno变量等
    10 #include <errno.h>
    11 // 下头文件包含一些时间函数
    12 #include <time.h>
    13 
    14 #define MAXLINE 100 
    15 #define LISTENQ 5
    16 
    17 int main(int argc, char **argv)
    18 {
    19     // 定义监听套接字描述符listenfd
    20     // 定义连接套接字描述符
    21     int listenfd, connfd;
    22     // 定义套接字变量servaddr( 注意这里存放的是客户端的信息 )
    23     struct sockaddr_in servaddr;
    24     // 定义字符数组buff暂存时间
    25     char buff[MAXLINE];
    26 
    27     // 定义时间相关变量
    28     time_t ticks;
    29     struct tm *ptm;
    30 
    31     // 创建一个网际字节流套接字
    32     if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    33         puts("创建网际套接字失败
    ");
    34         return 1;
    35     }
    36 
    37     // 将套接字变量servaddr清零
    38     bzero(&servaddr, sizeof(servaddr));
    39     // 给套接字变量的协议段赋值( AF_INET表示IPv4协议 )
    40     servaddr.sin_family = AF_INET;
    41     // 给套接字变量的端口段赋值( 13是时间服务器端口 )
    42     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    43     // 给套接字变量的IP段赋值( argv[1]存放服务器IP )
    44     servaddr.sin_port = htons(13);
    45 
    46     // 把指定的协议地址绑定到套接字
    47     if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0 ) {
    48         puts("绑定服务端口失败
    ");
    49         return 2;
    50     }
    51     // 将套接字转换为监听套接字类型
    52     if (listen(listenfd, LISTENQ) < 0) {
    53         puts("创建监听套接字失败
    ");
    54         return 3;
    55     }
    56 
    57     while (1) {
    58         // 等待客户呼叫,若收到呼叫则返回一个已连接套接字。
    59         connfd = accept(listenfd, (struct sockaddr *)NULL, NULL);
    60 
    61         /*
    62          * 获取时间并存放进buff数组
    63         */
    64         ticks = time(NULL);
    65         ptm = localtime(&ticks);
    66         snprintf(buff, sizeof(buff), "现在是北京时间:
    %d年 %d月 %d日 %d时 %d分", ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min);
    67 
    68         // 往客户端缓冲区中写入时间
    69         while (write(connfd, buff, strlen(buff)) < 0) {
    70             puts("写入数据失败
    ");
    71             return  4;
    72         }
    73         // 关闭连接
    74         if (close(connfd)) {
    75             puts("关闭套接字失败
    ");
    76             return 5;
    77         }
    78     }
    79 }

    运行测试

      1. 在一个终端用超级用户权限启动服务器:

       

      2. 在另一个终端中启动客户端并输进本机IP或者127.0.0.1:

      

  • 相关阅读:
    requests使用text可以查看源码
    正则表达式之search、sub
    【JS】深拷贝与浅拷贝的区别,实现深拷贝的几种方法
    php:对象(object)数据类型实例详解
    usage: git remote add [<options>] <name> <url> -f, --fetch fetch the remote branches --tags import all tags and associated objects when fetching
    PHP 可选参数
    php中文乱码问题的终极解决方案汇总
    html表单提交给PHP然后浏览器显示出了PHP的源代码
    wamp 安装
    wamp选择语言
  • 原文地址:https://www.cnblogs.com/scut-fm/p/3321508.html
Copyright © 2011-2022 走看看