TCP服务器/客户端:客户端recv()返回空白缓冲区
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP服务器/客户端:客户端recv()返回空白缓冲区相关的知识,希望对你有一定的参考价值。
我用C ++创建了一个TCP服务器/客户端。客户端从stdin获取输入char数组。然后客户端将其发送到服务器。服务器的工作是使用来自客户端的修改形式的消息进行响应。服务器的修改:用'X'替换输入消息的第一个字符
它在第一个输入消息上按预期工作,但客户端从第二个消息开始接收格式错误的数据。
./client.bin输出:
helloworld <-----stdin
TX: helloworld
RX: Xelloworld
test <-----stdin
TX: test
RX: 0est
somethingelse <-----stdin
TX: somethingelse
RX: Xest
./echoserver.bin输出:
RX: helloworld
TX: Xelloworld
RX: test
TX: Xest
RX: somethingelse
TX: Xomethingelse
echo server.曹操:
#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;
}
client.曹操
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.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 valread;
struct sockaddr_in address;
struct sockaddr_in server_addr;
char buffer[BUF_SIZE] = {0};
if ((sd = socket(AF_INET,SOCK_STREAM,0)) < 0)
error_exit("failed to create socket");
memset(&server_addr, '0', sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
if (inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) <= 0)
error_exit("Invalid Address");
if (connect(sd,(struct sockaddr*)&server_addr,sizeof(server_addr)) < 0)
error_exit("Connection Failure");
std::cin >> buffer;
while (buffer[0] != 'q')
{
std::cout << "TX: " << buffer << std::endl;
send(sd,buffer,BUF_SIZE-1,0);
if ( recv(sd,buffer,BUF_SIZE-1,0) <= 0)
error_exit("Failed to receive");
std::cout << "RX: " << buffer << std::endl;
memset(&buffer[0],'0', sizeof(buffer));
std::cin >> buffer;
}
return 0;
}
答案
你的发送调用总是发送1023个字节,但是你的recv调用并不一定要下载所有那些数据,你需要在循环中调用recv,直到你拥有所有发送的数据或传递MSG_WAITALL标志。
以上是关于TCP服务器/客户端:客户端recv()返回空白缓冲区的主要内容,如果未能解决你的问题,请参考以下文章