C++,socket连接,客户机发送文件给服务器,分片传送文件。遇到回车就出错,代码和问题在下面
文件名和套接字都在主函数,这两个没有问题。文件是一篇中文的文本文档。客户机发送:voidsendFile(charfilename[256],SOCKETcli_s){u...
文件名和套接字都在主函数,这两个没有问题。文件是一篇中文的文本文档。
客户机发送:
void sendFile(char filename[256], SOCKET cli_s)
{
using namespace std;
ifstream sendFile(filename);
char sendBuf[127];
while (!sendFile.eof()){
sendFile.get(sendBuf, sizeof(sendBuf));
send(cli_s, sendBuf, strlen(sendBuf) + 1, 0);
}
sendFile.close();
}
服务器接收:
void recvFile(char filename[256], SOCKET newsock)
{
using namespace std;
ofstream recvFile(filename, ios::out | ios::app);
char recvBuf[127];
while (strlen(recvBuf)){
recv(newsock, recvBuf, sizeof(recvBuf), 0);
recvFile << recvBuf;
}
recvFile.close();
}
几个问题:
sendBuf的缓冲池要设为多大合适?
send()会不会把上一次缓冲池里的内容覆盖?怎么实现客户机和服务器的有序收发?
服务器这边怎么判断客户机已经发送完了,我现在这个不行,会一直读取最后一次缓冲池的内容。
出错:
要传送的是一个中文文本文档,sendFile.get(sendBuf, sizeof(sendBuf));在第一个段落之前都没问题,但是碰到回车之后就不能正确读取文本内容了。发送的变成空,接收端直接退出了。
求帮忙分析一下,谢谢。如果要全部代码,我贴在后面。
http://pan.baidu.com/s/1gd1NRc3,全部代码的网盘地址,没发现上传在哪里,直接贴出来有点多,麻烦需要的话下一下。 展开
客户机发送:
void sendFile(char filename[256], SOCKET cli_s)
{
using namespace std;
ifstream sendFile(filename);
char sendBuf[127];
while (!sendFile.eof()){
sendFile.get(sendBuf, sizeof(sendBuf));
send(cli_s, sendBuf, strlen(sendBuf) + 1, 0);
}
sendFile.close();
}
服务器接收:
void recvFile(char filename[256], SOCKET newsock)
{
using namespace std;
ofstream recvFile(filename, ios::out | ios::app);
char recvBuf[127];
while (strlen(recvBuf)){
recv(newsock, recvBuf, sizeof(recvBuf), 0);
recvFile << recvBuf;
}
recvFile.close();
}
几个问题:
sendBuf的缓冲池要设为多大合适?
send()会不会把上一次缓冲池里的内容覆盖?怎么实现客户机和服务器的有序收发?
服务器这边怎么判断客户机已经发送完了,我现在这个不行,会一直读取最后一次缓冲池的内容。
出错:
要传送的是一个中文文本文档,sendFile.get(sendBuf, sizeof(sendBuf));在第一个段落之前都没问题,但是碰到回车之后就不能正确读取文本内容了。发送的变成空,接收端直接退出了。
求帮忙分析一下,谢谢。如果要全部代码,我贴在后面。
http://pan.baidu.com/s/1gd1NRc3,全部代码的网盘地址,没发现上传在哪里,直接贴出来有点多,麻烦需要的话下一下。 展开
1个回答
展开全部
客户机发送:
void sendFile(char filename[256], SOCKET cli_s)
{
using namespace std;
ifstream sendFile(filename, ios::binary); //二进制打开
sendFile.seekg(0, ios::end); //定位文件尾部
int len = f.tellg(); //取出文件长度
send(cli_s, &len, sizeof(len), 0); //发送文件长度
sendFile.seekg(0, 0); //定位文件头部
char sendBuf[4096];
int readBytes;
while (!sendFile.eof()){
readBytes = sendFile.get(sendBuf, sizeof(sendBuf));
if (readBytes>0) //逐个发送,直到读不出数据
send(cli_s, sendBuf, readBytes, 0);
}
sendFile.close();
}
服务器接收:
void recvFile(char filename[256], SOCKET newsock)
{
using namespace std;
int len = 0;
recv(newsock, &len, sizeof(len), 0); //先接收文件长度
if (len==0)
return;
ofstream recvFile(filename, ios::out | ios::app | ios::binary);//二进制
char recvBuf[4096];
int receivedBytes;
while(len>0) { //len表示残余长度
receivedBytes = recv(newsock, recvBuf, sizeof(recvBuf), 0);
if (receivedBytes>0) { //读到数据了
recvFile << recvBuf;
len -= receivedBytes; //残余长度递减
}
}
recvFile.close();
}
strlen只对英文有效。如果是中文的话,strlen是不准确的。只能按照二进制的方式来读写文件。
如果按照二进制的方式进行网络传输的话,接收端无法知道何时结束接收。所以通常,在发送数据流之前,先发送出去数据长度,这样接收端就知道何时结束接收数据了。
缓冲太小的话,读写文件次数会增多,影响性能。缓冲太大的话,占用内存多,而且堆栈上分配不出大的缓存。一般写65536一下吧,更详细的可以自己百度去。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询
广告 您可能关注的内容 |