TCP服务器/客户端:Client recv()返回空白缓冲区 我在C++中创建了一个TCP服务器/客户端。 客户端从stdin获取一个输入字符数组。 然后,客户端将其发送到服务器。 服务器的任务是使用来自客户机的消息的修改形式进行响应。 服务器的修改:将输入消息的第一个字符替换为“X”

TCP服务器/客户端:Client recv()返回空白缓冲区 我在C++中创建了一个TCP服务器/客户端。 客户端从stdin获取一个输入字符数组。 然后,客户端将其发送到服务器。 服务器的任务是使用来自客户机的消息的修改形式进行响应。 服务器的修改:将输入消息的第一个字符替换为“X”,c++,sockets,tcp,send,recv,C++,Sockets,Tcp,Send,Recv,它在第一条输入消息上按预期工作,但客户端从第二条消息开始接收格式错误的数据 /client.bin输出: helloworld <-----stdin TX: helloworld RX: Xelloworld test <-----stdin TX: test RX: 0est somethingelse <-----stdin TX: somethingelse RX: Xest RX: helloworld T

它在第一条输入消息上按预期工作,但客户端从第二条消息开始接收格式错误的数据

/client.bin输出:

helloworld          <-----stdin
TX: helloworld
RX: Xelloworld
test                <-----stdin
TX: test
RX: 0est
somethingelse       <-----stdin
TX: somethingelse
RX: Xest
RX: helloworld
TX: Xelloworld
RX: test
TX: Xest
RX: somethingelse
TX: Xomethingelse
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>   
#define  PORT 8080
#define  BUF_SIZE 1024

void error_exit(std::string text)
{
    std::cerr << text << std::endl;
    exit(1);
}

int main()
{
    int sd;
    int connection;
    int valread;
    int opt = 1;
    char buffer[BUF_SIZE] = {0};
    if ((sd = socket(AF_INET,SOCK_STREAM,0)) == 0)
        error_exit("socket failure");

    if (setsockopt(sd, SOL_SOCKET,SO_REUSEADDR,
            &opt, sizeof(opt)))
        error_exit("failed to set socket opts");

    sockaddr_in address;
    address.sin_family      = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port        = htons(PORT);
    if (bind(sd, (struct sockaddr *)&address, sizeof(address)) != 0)
        error_exit("failed to bind socket");

    if (listen(sd,3) < 0)
        error_exit("failed to listen");

    int addrlen = sizeof(address);
    if ((connection = accept(sd, (struct sockaddr*)&address,
                    (socklen_t*)&addrlen)) < 0)
        error_exit("failed to accept socket link");

    while (1)
    {
        memset(&buffer[0],'0', sizeof(buffer));
        if (recv(connection,buffer,BUF_SIZE-1,0) <= 0)
            break;
        std::cout << "RX: " << buffer << std::endl;
        buffer[0] = 'X';
        std::cout << "TX: " << buffer << std::endl;
        send(connection,buffer,BUF_SIZE,0);
    }
    return 0;
}
echoserver.cc:

helloworld          <-----stdin
TX: helloworld
RX: Xelloworld
test                <-----stdin
TX: test
RX: 0est
somethingelse       <-----stdin
TX: somethingelse
RX: Xest
RX: helloworld
TX: Xelloworld
RX: test
TX: Xest
RX: somethingelse
TX: Xomethingelse
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>   
#define  PORT 8080
#define  BUF_SIZE 1024

void error_exit(std::string text)
{
    std::cerr << text << std::endl;
    exit(1);
}

int main()
{
    int sd;
    int connection;
    int valread;
    int opt = 1;
    char buffer[BUF_SIZE] = {0};
    if ((sd = socket(AF_INET,SOCK_STREAM,0)) == 0)
        error_exit("socket failure");

    if (setsockopt(sd, SOL_SOCKET,SO_REUSEADDR,
            &opt, sizeof(opt)))
        error_exit("failed to set socket opts");

    sockaddr_in address;
    address.sin_family      = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port        = htons(PORT);
    if (bind(sd, (struct sockaddr *)&address, sizeof(address)) != 0)
        error_exit("failed to bind socket");

    if (listen(sd,3) < 0)
        error_exit("failed to listen");

    int addrlen = sizeof(address);
    if ((connection = accept(sd, (struct sockaddr*)&address,
                    (socklen_t*)&addrlen)) < 0)
        error_exit("failed to accept socket link");

    while (1)
    {
        memset(&buffer[0],'0', sizeof(buffer));
        if (recv(connection,buffer,BUF_SIZE-1,0) <= 0)
            break;
        std::cout << "RX: " << buffer << std::endl;
        buffer[0] = 'X';
        std::cout << "TX: " << buffer << std::endl;
        send(connection,buffer,BUF_SIZE,0);
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#定义端口8080
#定义BUF_大小1024
无效错误\u退出(标准::字符串文本)
{

std::cerr您的发送呼叫总是发送1023字节,但您的recv呼叫不一定下载所有数据,您需要在循环中调用recv,直到您拥有所有发送的数据或通过MSG_WAITALL标志。

您的发送呼叫总是发送1023字节,但您的recv呼叫不一定下载所有数据,您需要需要在循环中调用recv,直到您拥有所有发送的数据或传递MSG_WAITALL标志。

关于
memset
调用,请注意
'0'
不是字符串终止符。
'\0'
(或普通
0
)是。关于
memset
调用,请注意
'0'
不是字符串终止符。
'\0'
(或普通
0
)是。谢谢-我实现了recv()使用MSG_WAITALL,这很有效。一个遗留问题:我的客户端收据前缀为“0”。您的服务器发送的是BUF_大小而不是BUF_大小-1@user3313360零问题已经在对原始问题的评论中得到了回答。谢谢-我实现了recv()使用MSG_WAITALL,这很有效。一个遗留问题:我的客户端收据前缀为“0”。您的服务器发送的是BUF_大小而不是BUF_大小-1@user3313360零问题已在对原始问题的评论中得到回答。