2010-11-04 78 views
0

我正在学习使用套接字在C/C++中编程,并试图将二进制文件从服务器移动到客户端。这是我在服务器端的。(C++)通过套接字发送JPG文件

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。

任何建议,将不胜感激!

回答

2

strlen(buffer)计算字符串的长度。一个字符串被终止,你的二进制文件可能在文件结束之前有零。

所以strlen将返回小于文件大小。

改为使用size变量。

+0

糟糕,'size'变量实际上是一个常量。这里是'read'函数'ssize_t read(int fd,void * buf,size_t count)的描述;''read()尝试读取文件描述符fd中的字节计数到buf开始的缓冲区中。 ,返回的字节数被返回...... read()函数的返回值不等于服务器发送的字节量,也不是-1,所以没有错误(显然)! – 2010-11-04 06:56:53

1

您这里有两个问题:

  1. strlen()\0结束(见@taspeotis的回答)
  2. 您必须循环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