我正在学习使用套接字在C / C ++中编程,并试图将二进制文件从服务器移动到客户端。这是我在服务器端的内容。
ifstream file(argv[1],ios::binary|ios::ate)
size = new char[file.tellg()]
memblock = new char[size]
file.seekg(0,ios::beg);
file.read(memblock,size);
在读取了二进制文件的内容到memblock后,然后我使用套接字函数read传输它。
listen(sockd, 5);
newsock=accept(sockfd, NULL, NULL);
write(newsock, memblock, strlen(memblock));
delete[] memblock;
同时,在客户端
connect(sockfd, &servaddr, sizeof(servaddr));
read(sockfd, buffer, size);
ofstream output(argv[1], ios::binary);
output.write(buffer, strlen(buffer));
output.close();
delete[] buffer
我知道可能会出现一些错误,例如文件大小可能大于传输的数量,因此文件未完全复制。这只是该程序的第一步,因此我将进行必要的修改,以便稍后进行转移。
现在源代码本身是1kb(准确地说是714字节)。当我在服务器程序中加载它时,它正确地报告strlen(缓冲区)为715.当运行客户端时,它正确地报告读取715个字节,并且我得到一个与original_source_code.cpp相同的良好输出文件
但是,我有一个512字节的jpg文件。服务器程序将strlen(缓冲区)正确报告为512,但是,客户端只读取4个字节并停止。读取的字节数因文件格式不同而不同,但它从未真正读取完整的缓冲区。但是,文本文件通过套接字传输没有任何问题。
出现这种情况的原因是什么?我甚至无法在同一台机器上执行此操作,如运行服务器实例并要求客户端实例连接到127.0.0.1。
任何建议将不胜感激!
答案 0 :(得分:2)
strlen(buffer)
计算字符串的长度。字符串终止0,您的二进制文件在文件结束之前可能有零。
因此strlen
将返回小于文件大小的内容。
改为使用size
变量。
答案 1 :(得分:1)
这里有两个问题:
strlen()
以\0
结尾(请参阅@taspeotis的回答)read();
:int total_read = 0; int r = 0; while ( ( r = read(sockfd, buffer + total_read , size) ) > 0 ) total_read += r;
甚至更好:
connect(sockfd, &servaddr, sizeof(servaddr));
ofstream output(argv[1], ios::binary);
int byteread;
while ((byteread = read(sockfd, buffer, buffersize)) > 0 )
output.write(buffer, byteread);
output.close();
delete[] buffer