zoukankan      html  css  js  c++  java
  • Winsock.简单TCP

    PS:vs2017 编译C++代码 支持 XP:项目属性-->链接器-->系统-->需要的最小版本--> 输入 "5.1"

    1、ZC:测试:c向s 发送长度为0的数据,是可行的。(1)用s和c都在本机 测试,OK (2)用 冬的HP笔记本 和 我的联想小新笔记本 测试,OK

      ZC:要想 像UDP那样 像自己发送信息 来退出循环的话... 不太好办... 除非要 使用 非阻塞/异步模型(如 select模型、WSAAsyncSelect模型、WSAEventSelect模型、重叠IO模型),但是 有比较麻烦,还不如直接 使用 Qt的QTcpSocket(Qt的QUdpSocket会丢包,QTcpSocket用了之后 感觉还好)

    2、测试代码:

    // SampleTCP_01.cpp : This file contains the 'main' function. Program execution begins and ends there.
    //
    
    #include <iostream>
    #include <stdio.h>
    
    int main1();
    int main2();
    
    int main(int _argc, char** _argv)
    {
        std::cout << "Hello World!
    ";
    
        if (_argc <= 1)
        {
            printf("Command line no parameter .");
            return 0;
        }
    
        printf("%s
    ", _argv[0]);
        if (_argv[1][0] == 's')
            main1();
        else if (_argv[1][0] == 'c')
            main2();
        else
            printf("Unknown command line parameter : %s
    ", _argv[1]);
    
        return 0;
    }
    
    
    
    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    
    #include <iostream>
    #include <string>
    
    #include <winsock2.h>
    #pragma comment(lib, "ws2_32.lib")
    
    #define PORT 58888
    #define BUFFER_SIZE 256
    
    static const std::string kExitFlag = "-1";
    
    // 参考:http://c.biancheng.net/cpp/html/3030.html
    
    int main1()
    {
        WORD winsock_version = MAKEWORD(2, 2);
        WSADATA wsa_data;
        if (WSAStartup(winsock_version, &wsa_data) != 0) {
            std::cout << "Failed to init socket dll!" << std::endl;
            return 1;
        }
    
        SOCKET server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (server_socket == INVALID_SOCKET) {
            std::cout << "Failed to create server socket!" << std::endl;
            return 2;
        }
    
        sockaddr_in server_addr;
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(PORT);
        server_addr.sin_addr.S_un.S_addr = INADDR_ANY;
    
        if (bind(server_socket, (LPSOCKADDR)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
            std::cout << "Failed to bind port!" << std::endl;
            return 3;
        }
    
        if (listen(server_socket, 10)) {
            std::cout << "Failed to listen!" << std::endl;
            return 4;
        }
    
        // 循环接收数据。
        sockaddr_in client_addr;
        int client_addr_len = sizeof(client_addr);
        std::cout << "Wait for connecting..." << std::endl;
    
        // 程序一旦执行到 accept() 就会被阻塞(暂停运行),直到客户端发起请求。
        SOCKET client_socket = accept(server_socket, (SOCKADDR*)&client_addr, &client_addr_len);
        if (client_socket == INVALID_SOCKET) {
            std::cout << "Failed to accept!" << std::endl;
            return 5;
        }
    
        std::cout << "Succeed to receive a connection: " << inet_ntoa(client_addr.sin_addr) << std::endl;
    
        char recv_buf[BUFFER_SIZE] = {0};
        while (true)
        {
            // 接收数据。
            // 返回值是读取的字节数。没有内容时,等待请求。
            int ret = recv(client_socket, recv_buf, BUFFER_SIZE, 0);
            if (ret < 0) {
                std::cout << "Failed to receive data!" << std::endl;
                break;
            }
    
            printf("ret : %d
    ", ret);
            if (ret == 0)
            {
                printf("break
    ");
                break;
            }
    
            std::cout << "Receive from Client: " << recv_buf << std::endl;
            if (kExitFlag == recv_buf) {
                std::cout << "Exit!" << std::endl;
                break;
            }
    
            // 发送数据给客户端。
            char* send_data = (char*)"Hello, Tcp Client!
    ";
            send(client_socket, send_data, strlen(send_data), 0);
        }
    
        // 关闭套接字。
        closesocket(client_socket);
        closesocket(server_socket);
    
        // 释放dll。
        WSACleanup();
    
        return 0;
    }
    
    
    
    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    
    #include <iostream>
    #include <string>
    
    #include <winsock2.h>
    #pragma comment(lib, "ws2_32.lib")
    
    #define PORT 58888
    //#define SERVER_IP "127.0.0.1"
    #define SERVER_IP "192.168.2.102"
    #define BUFFER_SIZE 256
    
    //static const std::string kExitFlag = "-1";
    
    int main2()
    {
        // 初始化socket dll。
        WORD winsock_version = MAKEWORD(2, 2);
        WSADATA wsa_data;
        if (WSAStartup(winsock_version, &wsa_data) != 0) {
            std::cout << "Failed to init socket dll!" << std::endl;
            return 1;
        }
    
        SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (client_socket == INVALID_SOCKET) {
            std::cout << "Failed to create server socket!" << std::endl;
            return 2;
        }
    
        // 绑定IP和端口。
        sockaddr_in server_addr;
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(PORT);
        server_addr.sin_addr.S_un.S_addr = inet_addr(SERVER_IP);
        // connect() 向服务器发起请求,服务器的IP地址和端口号保存在 sockaddr_in 结构体中。直到服务器传回数据后,connect() 才运行结束。
        if (connect(client_socket, (LPSOCKADDR)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
            std::cout << "Failed to connect server!" << std::endl;
            return 3;
        }
    
        char recv_data[BUFFER_SIZE] = {0};
    
        while (true) {
            std::string data;
            std::cout << "Input data: ";
            std::cin >> data;
    
            //if (send(client_socket, data.c_str(), data.size(), 0) < 0) {
            if (send(client_socket, &recv_data[0], 0, 0) < 0) {
                std::cout << "Failed to send data!" << std::endl;
                break;
            }
    
            break;
    
            int ret = recv(client_socket, recv_data, BUFFER_SIZE, 0);
            if (ret < 0) {
                std::cout << "Failed to receive data!" << std::endl;
                break;
            }
    
            std::cout << "Receive data from server: " << recv_data << std::endl;
    
            if (recv_data == kExitFlag) {
                std::cout << "Exit!" << std::endl;
                break;
            }
        }
    
        closesocket(client_socket);
        WSACleanup();
    
        return 0;
    }

    3、vs2017 编译C++代码 支持 XP

      

    4、

    5、

  • 相关阅读:
    SVN补充
    java面试资料总结
    JAVABEAN EJB POJO区别
    Hibernate使用原生sql语句
    Discrete Logging(poj 2417)
    卡牌游戏(bzoj 3191)
    Activation(hdu 4089)
    Aeroplane chess(hdu 4405)
    LOOPS(hdu 3853)
    巧克力(zoj 1363)
  • 原文地址:https://www.cnblogs.com/cppskill/p/11986282.html
Copyright © 2011-2022 走看看