recv() 没有获取客户端使用 send() 发送的所有数据
recv() not getting all data sent by client using send()
我真的不知道这是否是网络、我的电脑或其他方面的某种延迟,我对套接字编程还很陌生,并且已经尝试了一段时间,实现了一个简单的框架来简化我在 class 的未来项目中的工作,我在遇到的问题中使用了这些功能:
void TCPSocket::send(const std::string& message, int flags) {
if (isListening || !isConnected) {
throw ConnectionException("Can't send message from a socket that is not connected");
}
int msgLength = message.length();
int bytesLeft = msgLength;
int bytesSent;
const char* cMessage = message.c_str();
while (bytesSent < msgLength) {
const char* cMessageLeft = cMessage + bytesSent;
int result = ::send(socketFd, cMessageLeft, bytesLeft, flags);
if (result == -1) {
throw ConnectionException("Could not send message. Error: " + std::string(strerror(errno)));
}
bytesLeft -= result;
bytesSent += result;
}
}
std::string TCPSocket::recv(unsigned int maxlen, int flags) {
if (isListening || !isConnected) {
throw ConnectionException("Can't receive message in a socket that is not connected");
}
char buffer[maxlen+1];
int result = ::recv(socketFd, buffer, maxlen, flags);
if (result == -1) {
throw ConnectionException("Could not receive message. Error: " + std::string(strerror(errno)));
}
if (result == 0) {
isConnected = false;
throw ClosedConnection("Client closed connection.");
}
buffer[result] = '[=10=]';
std::string message(buffer);
return message;
}
它只用一条消息就很好用,我使用不同的可执行文件接收和发送完全没有问题,但我尝试发送超过 1 条消息并且我的问题开始了,有时我让服务器接收 1 条消息,有时它会得到 none 并且当我只添加几个 printf() 时它会收到所有这些,有人可以向我解释为什么会这样吗?
客户代码:
int main() {
TCPSocket cl1(0);
try {
cl1.connect("localhost", 1170);
for (int i = 0; i < 5; i++) {
//printf("Esperando 5s... ");
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//printf("Pronto!\n\n");
cl1.send("Thank you!\n");
//printf("Msg enviada\n\n");
}
cl1.close();
}
catch( std::exception &e) {
std::cout << e.what() << std::endl;
}
}
服务器代码:
int main() {
TCPSocket sv1(0);
try {
sv1.bind(1170);
sv1.listen();
TCPSocket client = sv1.accept();
printf("Cliente conectado\n");
try {
for (;;) {
//client.send("Welcome !\n");
std::cout << client.recv(256) << std::endl;
}
}
catch (const ClosedConnection & x) {
printf("Connection closed\n");
}
}
catch( std::exception &e) {
std::cout << e.what() << std::endl;
}
}
如果我取消注释客户端代码中的 printfs,所有数据都会在服务器上接收。
澄清一下,我以 5 秒的间隔发送消息,recv() 仍然只读取第一个并且它会阻塞直到 client
完成它的执行,从不读取应该在的其余消息缓冲区。出于某种原因,在客户端代码上使用 printfs 可以使应用程序 运行 正常。
您似乎没有初始化 bytesSent
因此它实际发送数据的次数似乎不确定。
int bytesSent = 0;
我真的不知道这是否是网络、我的电脑或其他方面的某种延迟,我对套接字编程还很陌生,并且已经尝试了一段时间,实现了一个简单的框架来简化我在 class 的未来项目中的工作,我在遇到的问题中使用了这些功能:
void TCPSocket::send(const std::string& message, int flags) {
if (isListening || !isConnected) {
throw ConnectionException("Can't send message from a socket that is not connected");
}
int msgLength = message.length();
int bytesLeft = msgLength;
int bytesSent;
const char* cMessage = message.c_str();
while (bytesSent < msgLength) {
const char* cMessageLeft = cMessage + bytesSent;
int result = ::send(socketFd, cMessageLeft, bytesLeft, flags);
if (result == -1) {
throw ConnectionException("Could not send message. Error: " + std::string(strerror(errno)));
}
bytesLeft -= result;
bytesSent += result;
}
}
std::string TCPSocket::recv(unsigned int maxlen, int flags) {
if (isListening || !isConnected) {
throw ConnectionException("Can't receive message in a socket that is not connected");
}
char buffer[maxlen+1];
int result = ::recv(socketFd, buffer, maxlen, flags);
if (result == -1) {
throw ConnectionException("Could not receive message. Error: " + std::string(strerror(errno)));
}
if (result == 0) {
isConnected = false;
throw ClosedConnection("Client closed connection.");
}
buffer[result] = '[=10=]';
std::string message(buffer);
return message;
}
它只用一条消息就很好用,我使用不同的可执行文件接收和发送完全没有问题,但我尝试发送超过 1 条消息并且我的问题开始了,有时我让服务器接收 1 条消息,有时它会得到 none 并且当我只添加几个 printf() 时它会收到所有这些,有人可以向我解释为什么会这样吗?
客户代码:
int main() {
TCPSocket cl1(0);
try {
cl1.connect("localhost", 1170);
for (int i = 0; i < 5; i++) {
//printf("Esperando 5s... ");
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//printf("Pronto!\n\n");
cl1.send("Thank you!\n");
//printf("Msg enviada\n\n");
}
cl1.close();
}
catch( std::exception &e) {
std::cout << e.what() << std::endl;
}
}
服务器代码:
int main() {
TCPSocket sv1(0);
try {
sv1.bind(1170);
sv1.listen();
TCPSocket client = sv1.accept();
printf("Cliente conectado\n");
try {
for (;;) {
//client.send("Welcome !\n");
std::cout << client.recv(256) << std::endl;
}
}
catch (const ClosedConnection & x) {
printf("Connection closed\n");
}
}
catch( std::exception &e) {
std::cout << e.what() << std::endl;
}
}
如果我取消注释客户端代码中的 printfs,所有数据都会在服务器上接收。
澄清一下,我以 5 秒的间隔发送消息,recv() 仍然只读取第一个并且它会阻塞直到 client
完成它的执行,从不读取应该在的其余消息缓冲区。出于某种原因,在客户端代码上使用 printfs 可以使应用程序 运行 正常。
您似乎没有初始化 bytesSent
因此它实际发送数据的次数似乎不确定。
int bytesSent = 0;