TCP服务器/客户端:Client recv()返回空白缓冲区 我在C++中创建了一个TCP服务器/客户端。 客户端从stdin获取一个输入字符数组。 然后,客户端将其发送到服务器。 服务器的任务是使用来自客户机的消息的修改形式进行响应。 服务器的修改:将输入消息的第一个字符替换为“X”
它在第一条输入消息上按预期工作,但客户端从第二条消息开始接收格式错误的数据 /client.bin输出: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
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零问题已在对原始问题的评论中得到回答。