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 }
  • 相关阅读:
    微信小程序HTTPS
    微信商城-1简介
    va_list
    Event log c++ sample.
    EVENT LOGGING
    Analyze Program Runtime Stack
    unknow table alarmtemp error when drop database (mysql)
    This application has request the Runtime to terminate it in an unusual way.
    How to check if Visual Studio 2005 SP1 is installed
    SetUnhandledExceptionFilter
  • 原文地址:https://www.cnblogs.com/hdtianfu/p/2732614.html
Copyright © 2011-2022 走看看