TCP Server/Client : 客户端 recv() returns 空白缓冲区
TCP Server/Client : client recv() returns blank buffer
我用 C++ 创建了一个 TCP Server/Client。
客户端从标准输入中获取一个输入字符数组。
客户端然后将其发送到服务器。
服务器的工作是用来自客户端的消息的修改形式进行响应。
服务器的修改:将输入消息的第一个字符替换为 '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
echoserver.cc:
#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.cc
#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旗帜。
我用 C++ 创建了一个 TCP Server/Client。 客户端从标准输入中获取一个输入字符数组。 客户端然后将其发送到服务器。 服务器的工作是用来自客户端的消息的修改形式进行响应。 服务器的修改:将输入消息的第一个字符替换为 '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
echoserver.cc:
#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.cc
#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旗帜。