zoukankan      html  css  js  c++  java
  • 基本的TCP socket编程示例 时间服务器及客户端

    服务器端的编写

        1.  使用socket函数新建一个套接字,指定其 协议族family(AF_INET)、协议类型type(SOCK_STREAM)、协议(0, 系统根据family和type指定默认值)

        2.  使用bind函数将本地协议地址绑定到套接字上,

        3.  使用listen函数监听客户端发来的请求

        4.  使用accept函数循环接受客户端的请求

        5.  使用send和recv函数发送和接收数据 

    客户端程序的编写

         1.  使用socket函数创建一个套接字

         2.  使用connect函数连接服务器

         3.  使用send和recv发送和接受数据

    示例如下:

     由于使用winsock之前需要初始化winsock DLL,所以我将winsock的初始化和释放封装到了一个类中,如下:

      1 // 初始化winsock

     2 #include <winsock2.h>
     3 #include <iostream>
     4 class SockInitializer{
     5     public:
     6         SockInitializer()
     7         {
     8             WORD versionRequired = MAKEWORD(22);
     9             WSADATA wsaData;
    10             int ret = WSAStartup(versionRequired, &wsaData);
    11             if (0 != ret){
    12                 std::cerr << "socket initialize failed";
    13                 exit(1);
    14             }
    15         }
    16         ~SockInitializer(){
    17             WSACleanup();
    18         }
    19 };

    接下来是服务器端的编写:

    注:关于listen的第二个参数backlog,我们可以为其指定一个环境变量,以随时调整它的值 

     1 // 服务器端程序
     2 #include <winsock2.h>
     3 #include <cstdio>
     4 #include <ctime>
     5 
     6 using namespace std;
     7 
     8 SockInitializer sockInitializer;   // 初始化winsock
     9 
    10 int main()
    11 {
    12     SOCKET listenfd, connfd;
    13     sockaddr_in serverAddr;
    14     
    15     char buf[100];
    16     memset(buf, 0sizeof(buf));
    17 
    18     // 1. 建立一个socket
    19     listenfd = socket(AF_INET, SOCK_STREAM, 0); 
    20     if (INVALID_SOCKET == listenfd){
    21         cerr << "invalid socket";
    22         exit(1);
    23     }
    24 
    25     // 2. 绑定到本地的端口
    26     serverAddr.sin_family = AF_INET;
    27     serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);  // 使用通配地址
    28     serverAddr.sin_port = htons(13);                 // 13是时间服务器的端口号
    29 
    30     int ret = bind(listenfd, (sockaddr*)&serverAddr, sizeof(serverAddr) );
    31     if (ret != 0){
    32         cerr << "error on bind:" << WSAGetLastError();
    33         exit(1);
    34     }
    35 
    36     // 3. 开始监听客户端请求
    37     listen(listenfd, SOMAXCONN);  // listen的第二个参数指定了套接字排队的最大连接个数,
    38                                   // 我们为其指定 SOMAXCONN ,表示系统支持的最大连接个数
    39     // 4. 循环接受客户端的请求
    40     while (true){
    41         cout << "accept ..." << endl;
    42         connfd = accept(listenfd, (sockaddr*)NULL, NULL);  // 这里我们不需要接受客户端的sockaddr, 因此指定为NULL
    43         if (INVALID_SOCKET == connfd){
    44             cerr << "error on accept:" << WSAGetLastError() << endl;
    45             continue;
    46         }
    47         cout << "successfully accept socket:" << connfd << endl;
    48         time_t ticks = time(NULL);
    49         snprintf(buf, sizeof(buf), "%.24s\r\n", ctime(&ticks) );
    50         send(connfd, buf, strlen(buf), 0 );
    51 
    52         closesocket(connfd);
    53     }
    54 } 

      

    客户端程序:

      1 // 客户端程序

     2 #include <winsock2.h>
     3 #include <cstdio>
     4 #include <iostream>
     5 
     6 using namespace std;
     7 
     8 SockInitializer sockInitializer; // 初始化winsock
     9 
    10 int main(int argc, char **argv)
    11 {
    12     if (argc != 2){
    13         cerr << "usage: client <ipaddress>";
    14         exit(1);
    15     }
    16 
    17     // 1. 创建套接字
    18     SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
    19     if (sockfd == INVALID_SOCKET){
    20         cerr << "invalid socket";
    21         exit(1);
    22     }
    23 
    24     // 2. 连接至服务器
    25     sockaddr_in serverAddr;
    26     memset(&serverAddr, 0sizeof serverAddr);
    27     serverAddr.sin_family = AF_INET;
    28     serverAddr.sin_port = htons(13);
    29     serverAddr.sin_addr.s_addr = inet_addr(argv[1]);
    30 
    31     int ret = connect(sockfd, (SOCKADDR*)&serverAddr, sizeof serverAddr);  // 指定服务器的地址
    32     if (0 != ret){
    33         cout << "error on connect:" << WSAGetLastError();
    34         exit(1);
    35     }
    36 
    37     // 3. 接受数据
    38     char buf[100];
    39     int n;
    40     while ( 0 != (n = recv(sockfd, buf, sizeof buf, 0) ) ){
    41         buf[n] = '\0';
    42         cout << buf;
    43     }
    44 }
  • 相关阅读:
    第二十篇 sys模块
    第十九章 Python os模块,pathlib 判断文件是目录还是文件
    第三篇 Postman之 Tests(后置处理器,断言)
    第十八篇 模块与包--time&random模块&模块导入import(os.path.dirname(os.path.abspath(__file__)))
    Sublime text3最全快捷键清单
    第十七篇 Python函数之闭包与装饰器
    第二篇 Postman的高阶使用之配置全局变量及局部变量的调用及设置方法(手动方法)
    第六篇 常用请求协议之post put patch 总结
    第十六篇 Python之迭代器与生成器
    PCL—低层次视觉—关键点检测(Harris)
  • 原文地址:https://www.cnblogs.com/hdtianfu/p/2732614.html
Copyright © 2011-2022 走看看