通过TCP发送图片
Sending Picture via TCP
我正在尝试使用TCP将jpg文件从客户端发送到服务器。当图片到达服务器端时,我无法打开它,而且接收到的图片大小比发送的图片大(发送=880字节,接收=894字节)。你们中有人知道如何解决这个问题吗?这是我的代码:
客户端代码:
static int send_server_image(SOCKET sock){
int n = 0;
int siz = 0;
FILE *picture;
char buf[50];
char *s="";
cout << "Getting image size" << endl;
picture = fopen("C:\Users\n.b\Desktop\c++\TCP\tcp_client_image_pp\test.jpg", "r");
fseek(picture, 0, SEEK_END);
siz = ftell(picture);
cout << siz << endl; // Output 880
cout << "Sending picture size to the server" << endl;
sprintf(buf, "%d", siz);
if((n = send(sock, buf, sizeof(buf), 0)) < 0)
{
perror("send_size()");
exit(errno);
}
char Sbuf[siz];
cout << "Sending the picture as byte array" << endl;
fseek(picture, 0, SEEK_END);
siz = ftell(picture);
fseek(picture, 0, SEEK_SET); //Going to the beginning of the file
while(!feof(picture)){
fread(Sbuf, sizeof(char), sizeof(Sbuf), picture);
if((n = send(sock, Sbuf, sizeof(Sbuf), 0)) < 0)
{
perror("send_size()");
exit(errno);
}
memset(Sbuf, 0, sizeof(Sbuf));
}
}
服务器代码:
static int recv_client_image(SOCKET sock){
int n = 0;
cout << "Reading image size" << endl;
char buf[50];
int siz = 0;
if ((n = recv(sock, buf, sizeof(buf), 0) <0)){
perror("recv_size()");
exit(errno);
}
siz = atoi(buf);
cout << siz << endl; // 880 output
char Rbuffer[siz];
cout << "Reading image byte array" << endl;
n = 0;
if ((n = recv(sock, Rbuffer, sizeof(Rbuffer), 0)) < 0){
perror("recv_size()");
exit(errno);
}
cout << "Converting byte array to image" << endl;
FILE *image;
image = fopen("recu.jpg", "w");
fwrite(Rbuffer, sizeof(char), sizeof(Rbuffer), image);
fclose(image);
cout << "done" << endl;
}
谢谢。
您使用的是可变长度数组,它不是标准C++(ref)。即使编译器接受了它,也应该避免在上面使用sizeof
。
你的while(!feof(picture))
有问题。您从文件中读取了siz字节,没有任何错误,也没有设置eof标志。在第二次读取时,您读取0个字节并设置标志,但也发送另一个缓冲区。
你应该改为写:
while(!feof(picture)){
n = fread(Sbuf, sizeof(char), siz, picture);
if (n > 0) { /* only send what has been read */
if((n = send(sock, Sbuf, siz, 0)) < 0) /* or (better?) send(sock, Sbuf, n, 0) */
{
perror("send_data()");
exit(errno);
}
}
/* memset(Sbuf, 0, sizeof(Sbuf)); useless for binary data */
}
服务器部分相同:
if ((n = recv(sock, Rbuffer, siz, 0)) < 0){
perror("recv_size()");
exit(errno);
}
cout << "Converting byte array to image" << endl;
FILE *image;
image = fopen("recu.jpg", "w");
fwrite(Rbuffer, sizeof(char), siz, image);
fclose(image);
还有最后一种错误的可能性,至少如果你在一个像Windows这样的区分文本和二进制文件的平台上,那就是你忘记了以二进制模式打开文件,这可能会破坏jpg图像。因为在二进制文件的窗口中,字节0x10被视为新行(n'
),并被写入为2字节0x0d 0x10(rn
)。
因此,您必须在rb
模式下打开输入文件,在wb
模式下打开输出文件。
已解决:
Serge Ballesta的所有更正都是正确的。但问题出在我打开文件的方式上。
您需要以二进制模式("rb"表示读取,"wb"表示写入)打开文件,而不是默认的文本模式。
客户:
picture = fopen("C:\Users\n.b\Desktop\c++\TCP\tcp_client_image_pp\test.jpg", "rb");
服务器:
image = fopen("recu.jpg", "wb");
这是主要问题。非常感谢。
相关文章:
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 通过TCP的PvP通信问题
- AWS IoT 开发工具包:通过 TCP 端口 443 使用 MQTT
- 通过单独的 tcp 流建立 http 连接
- 为什么当通过 TCP 发送的消息速率增加时,请求-响应消息对的延迟会降低?
- 通过 tcp 发送 C# 类并在 C++ 上反序列化
- 当通过tcp接收编码图像的消息时,zmq在第二个循环中崩溃
- 是否有一种标准化的方法通过TCP/IP网络发送JPG图像
- 通过TCP将数据从C++客户端发送到JSON服务器
- 如何将通过TCP发送数据的数据从C++转换为Java
- 通过TCP连接到Wi-Fi上的0.0.0.0,而侦听器PC有活动的Wi-Fi,以太网没有'不起作用
- 通过 TCP 套接字发送大型 base64 字符串
- 仅通过建立一次TCP连接将Recv从客户端发送到服务器套接字
- 如何<double>通过TCP套接字将CLI 列表^发送到本机C++?
- 如何让客户端通过modbus-tcp协议与多个服务器通信?
- 如何通过TCP/IP Winsock发送双型数据
- C++ SDL2 Net:通过 TCP 的整数数组
- 通过C 中的TCP/IP协议发送.TXT文件
- 如何避免通过TCP/IP SSH隧道在数据传输中重复读取数据
- 通过TCP在客户端/ C#服务器之间传输文件C++