C++ (C+;+;)通过套接字发送JPG文件

C++ (C+;+;)通过套接字发送JPG文件,c++,sockets,binaryfiles,C++,Sockets,Binaryfiles,我正在学习用带套接字的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之后,我使用socket函数read将其传输 liste

我正在学习用带套接字的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之后,我使用socket函数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字节,我得到了一个与原始的_source _code.cpp相同的输出文件

但是,我有一个512字节的jpg文件。服务器程序报告strlen(缓冲区)正确为512,但是,客户端仅读取4个字节并停止。读取的字节数随文件格式的不同而不同,但它从未真正读取完整的缓冲区。但是,文本文件通过套接字传输,没有任何问题

发生这种情况的原因是什么?我甚至无法在同一台机器上执行此操作,例如运行服务器实例并要求客户端实例连接到127.0.0.1

如有任何建议,将不胜感激

strlen(缓冲区)
计算字符串的长度。如果字符串以0结尾,则二进制文件可能在文件结尾之前包含零

因此
strlen
将返回小于文件大小的值

使用
size
变量。

strlen(缓冲区)
计算字符串的长度。如果字符串以0结尾,则二进制文件可能在文件结尾之前包含零

因此
strlen
将返回小于文件大小的值


请改用
size
变量。

这里有两个问题:

  • strlen()
    \0
    结尾(参见@taspeotis的答案)
  • 你必须循环
    read()手动:
  • 或者更好:

    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 
    

    这里有两个问题:

  • strlen()
    \0
    结尾(参见@taspeotis的答案)
  • 你必须循环
    read()手动:
  • 或者更好:

    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 
    

    哎呀,
    size
    变量实际上是一个常量。以下是
    read
    函数
    ssize\u t read(intfd,void*buf,size\u t count)的说明'read()尝试从文件描述符fd向缓冲区读取最多个字节,从buf开始。`成功后,返回读取的字节数'。。。read()函数的返回值不等于服务器发送的字节数,也不是-1,因此没有错误(显然)!哎呀,
    size
    变量实际上是一个常量。以下是
    read
    函数
    ssize\u t read(intfd,void*buf,size\u t count)的说明'read()尝试从文件描述符fd向缓冲区读取最多个字节,从buf开始。`成功后,返回读取的字节数'。。。read()函数的返回值不等于服务器发送的字节数,也不是-1,因此没有错误(显然)!