自学内容网 自学内容网

C++ socket编程(3)

前面文章,介绍了一个简单socket通讯Demo, 客户端和服务器进行简单的交互。两个代码都很简单,如果情况一复杂,就会出错。这节我们把代码完善一下,实现一个客户端输入,发送,服务器echo的交互。本文介绍客户端代码修改。

客户端其他函数修改同服务器端,可以看上一篇文章。

当服务器启动需要时间时, connect可能需要等待:

    int i = 60; //timeout, 60s.
    while (i)
    {
        if (connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)) == 0)
        {
            break;
        }
        else
        {
            Sleep(1000);    //1s.
            --i;
        }
    }
    if (i == 0)
    {
        std::cout << "connect error." << std::endl;
        closesocket(sock);
        sock = INVALID_SOCKET;
        return;
    }

这里等1分钟,如果服务器还是没起来,就退出了。

客户端的整个代码如下:

#include <iostream>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <string>
#pragma comment(lib, "ws2_32.lib")

#define SOCKET_ADDR "127.0.0.1"
#define SOCKET_PORT 1234

void runSocketClient()
{
    SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock == INVALID_SOCKET)
    {
        std::cout << "socket error." << std::endl;
        return;
    }

    struct sockaddr_in sockAddr;
    sockAddr.sin_family = PF_INET;
    inet_pton(AF_INET, SOCKET_ADDR, &sockAddr.sin_addr.s_addr);
    sockAddr.sin_port = htons(SOCKET_PORT);
    int i = 60; //timeout, 60s.
    while (i)
    {
        if (connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)) == 0)
        {
            break;
        }
        else
        {
            Sleep(1000);    //1s.
            --i;
        }
    }
    if (i == 0)
    {
        std::cout << "connect error." << std::endl;
        closesocket(sock);
        sock = INVALID_SOCKET;
        return;
    }

    int ret = 0;
    char szBuffer[MAXBYTE] = { 0 };
    ret = recv(sock, szBuffer, MAXBYTE, NULL);
    if (ret == 0)
    {
        std::cout << "recv == 0." << std::endl;
        closesocket(sock);
        sock = INVALID_SOCKET;
        return;
    }
    else
    {
        std::cout << szBuffer << std::endl;
    }

    while (1)
    {
        memset(szBuffer, 0, MAXBYTE);
        std::string line;
        std::getline(std::cin, line);
        if (line.size() > MAXBYTE-1) {
            line = line.substr(0, MAXBYTE-1);
        }
        strncpy_s(szBuffer, line.c_str(), MAXBYTE);

        if (strncmp(szBuffer, "exit", MAXBYTE) == 0)
        {
            break;
        }
        ret = send(sock, szBuffer, strlen(szBuffer) + sizeof(char), NULL);
        if (ret != strlen(szBuffer) + sizeof(char))
        {
            std::cout << "send error." << std::endl;
            continue;
        }
        else
        {
            std::cout << "send:" << szBuffer << std::endl;
        }
        memset(szBuffer, 0, MAXBYTE);
        ret = recv(sock, szBuffer, MAXBYTE, NULL);
        if (ret == 0)
        {
            std::cout << "recv == 0." << std::endl;
            closesocket(sock);
            sock = INVALID_SOCKET;
            break;
        }
        else
        {
            std::cout << "recv:" << szBuffer << std::endl;
        }
    }

    if (sock != INVALID_SOCKET)
    {
        closesocket(sock);
        sock = INVALID_SOCKET;
    }
}


int main()
{
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    runSocketClient();

    WSACleanup();

    return 0;
}

客户端测试:

connected.
hello
send:hello
recv:hello
123456
send:123456
recv:123456
exit


原文地址:https://blog.csdn.net/caz28/article/details/142835373

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!