我正在尝试使用套接字编程将文件发送到服务器 . 我的服务器和客户端能够成功连接到彼此,但我希望下面的while循环遍历整个文件并将其添加到服务器 . 我遇到的问题是它只发送第一个块而不是其余部分 .
在客户端,我有以下内容:
memset(szbuffer, 0, sizeof(szbuffer)); //Initialize the buffer to zero
int file_block_size;
while ((file_block_size = fread(szbuffer, sizeof(char), 256, file)) > 0){
if (send(s, szbuffer, file_block_size, 0) < 0){
throw "Error: failed to send file";
exit(1);
} //Loop while there is still contents in the file
memset(szbuffer, 0, sizeof(szbuffer)); //Reset the buffer to zero
}
在服务器端,我有以下内容:
while (1)
{
FD_SET(s, &readfds); //always check the listener
if (!(outfds = select(infds, &readfds, NULL, NULL, tp))) {}
else if (outfds == SOCKET_ERROR) throw "failure in Select";
else if (FD_ISSET(s, &readfds)) cout << "got a connection request" << endl;
//Found a connection request, try to accept.
if ((s1 = accept(s, &ca.generic, &calen)) == INVALID_SOCKET)
throw "Couldn't accept connection\n";
//Connection request accepted.
cout << "accepted connection from " << inet_ntoa(ca.ca_in.sin_addr) << ":"
<< hex << htons(ca.ca_in.sin_port) << endl;
//Fill in szbuffer from accepted request.
while (szbuffer > 0){
if ((ibytesrecv = recv(s1, szbuffer, 256, 0)) == SOCKET_ERROR)
throw "Receive error in server program\n";
//Print reciept of successful message.
cout << "This is the message from client: " << szbuffer << endl;
File.open("test.txt", ofstream::out | ofstream::app);
File << szbuffer;
File.close();
//Send to Client the received message (echo it back).
ibufferlen = strlen(szbuffer);
if ((ibytessent = send(s1, szbuffer, ibufferlen, 0)) == SOCKET_ERROR)
throw "error in send in server program\n";
else cout << "Echo message:" << szbuffer << endl;
}
}//wait loop
} //try loop
上面的代码是客户端和服务器之间连接的设置,效果很好 . 它处于一个等待接收新请求的常量while循环中 . 问题在于我的缓冲区 . 一旦我发送第一个缓冲区,下一个缓冲区似乎没有通过 . 有谁知道我可以做什么来设置服务器接收多个缓冲区?我尝试了一段时间但没有运气 .
2 回答
不,您的服务器只从客户端读取一次 . 你必须循环,就像发送循环一样 .
从服务器发送文件的代码似乎正确发送文件的连续部分 .
您的代码似乎打算从客户端接收文件,执行以下步骤:
1)等待并接受套接字 .
2)从套接字读取最多256个字节 .
3)将这些字节写回套接字 .
此时,代码似乎返回等待另一个连接,并保持原始连接打开,并且至少基于您发布的代码,显然泄漏了文件描述符 .
所以,问题似乎是客户端和服务器不同意应该发生什么 . 客户端尝试发送整个文件,但不从套接字读取 . 服务器从套接字读取前256个字节,并将其写回客户端 .
当然,完全可能的是未显示的部分代码实现了一些缺失的部分,但是在发送方正在做什么和接收方正在做什么之间肯定存在脱节 .