首页 > 解决方案 > 从服务器传输到客户端的消息没有出现

问题描述

我正在使用 WinSock2 在 C++ (Visual Studio 2017) 中编写客户端-服务器应用程序。我看了 YouTube 教程,做了一个服务器和客户端。启动时,连接已建立。但是来自服务器的消息不会传输到客户端。

这是我的服务器。

//Server
#pragma comment(lib, "ws2_32.lib")
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <iostream>

int main() {

    //WinSock Startup
    WSAData wsaData;
    WORD DllVersion = MAKEWORD(2, 1);
    if (WSAStartup(DllVersion, &wsaData) != 0) { //If WSAStartup returns anything ither than 0, than that means an error has occured in the WinSock Startup
        MessageBoxA(NULL, "WinSock startup failed", "Error", MB_OK | MB_ICONERROR);
        exit(1);
    }

    SOCKADDR_IN addr; //Address tha the will bind our listening socket to
    int addrlen = sizeof(addr); //lenght of the address (required for accept call)
    addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //Broadcast locally
    addr.sin_port = htons(1111); //Port
    addr.sin_family = AF_INET; //IPv4 Socket

    SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL); //Create socket to listen for new connections
    bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); //Bind the address to the socket
    listen(sListen, SOMAXCONN); //Places sListen socket in a state in which is in listening for an incoming connection. Note: SOMAXCONN = Socket Outstanding Max Connections

    SOCKET newConnection; // Socket to hold the client's connection
    newConnection = accept(sListen, (SOCKADDR*)&addr, &addrlen); //Accept a new connection
    if (newConnection == 0) { //If accepting the client's connection failed
        std::cout << "Failed to accept the client's connection" << std::endl;
    }
    else { //If client connection properly accepted
        std::cout << "Client connected!" << std::endl;
        char MOID[256] = "Welcome! This is a Message of the Day."; //Create buffer with message of the day
        send(newConnection, MOID, sizeof(MOID), NULL); //Send MOID buffer
    }
    system("pause");
    return 0;
}

这是这样一个客户。

//Client
#pragma comment (lib, "ws2_32.lib")
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <iostream>

int main() {

    //WinSock Startup
    WSAData wsaData;
    WORD DllVersion = MAKEWORD(2, 1);
    if (WSAStartup(DllVersion, &wsaData) != 0) { //If WSAStartup returns anything ither than 0, than that means an error has occured in the WinSock Startup
        MessageBoxA(NULL, "WinSock startup failed", "Error", MB_OK | MB_ICONERROR); 
        exit(1);
    }

    SOCKADDR_IN addr; //Address to be binded to our Connection socket
    int sizeofaddr = sizeof(addr); //Need sizeofaddr for the connect function
    addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //Address = localhoct (this pc)
    addr.sin_port = htons(1111); //Port =  1111
    addr.sin_family = AF_INET; //IPv4 Socket

    SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL); //Set connection socket
    if (connect(Connection, (SOCKADDR*)&addr, sizeofaddr) != 0) { //If we are unable to connect...
        MessageBoxA(NULL, "Failed to connect", "Error", MB_OK | MB_ICONERROR);
        return 0; //Failed to connect
    }
    std::cout << "Connected!" << std::endl;
    char MOID[256];
    recv(Connection, MOID, sizeof(MOID), NULL); //Recieve Message of the day  buffer into MOID array 
    std::cout << "MOID:" << std::endl;
    system("pause");

    return 0;
}

应发送此消息:“欢迎!这是今日消息。” 请告诉我为什么没有发送消息,我该如何解决?

标签: c++winsock2

解决方案


应发送此消息:“欢迎!这是今日消息。”

你的期望是错误的。TCP 套接字是一个流套接字(由 SOCK_STREAM 参数建议),这意味着它具有某些属性。对于流,这意味着将按照发送的顺序接收数据(或者您会收到错误消息)。尽管没有人保证您会以一个数据包的形式收到整个消息。您可以逐个字节或 2 个字节组,或整个消息或任何其他变体获取它们。所以你的程序应该处理所有这些 - 在循环中读取数据,直到你得到你的整个消息。你怎么知道收到的整个消息?这取决于您 - 有些事先发送消息大小,有些使用消息结束标记(这可能是'\0'您的消息的符号)。但是期望你一次获得全部信息是错误的,它不会那样工作。除此之外,您还需要检查什么recv()返回 - 即它收到了多少字节,或者是否发生了任何错误。


推荐阅读