通过TCP传输二进制文件需要遵循以下步骤和注意事项:
一、传输流程
发送文件元数据 首先发送文件的大小(通常使用`long`类型),以便接收方知道需要读取多少数据。
```c
send(sock, &fileSize, sizeof(fileSize));
```
传输文件内容
按顺序发送文件的二进制数据,可以使用循环调用`send`或`sendall`函数,确保所有数据都被发送。
关闭连接
数据传输完成后,关闭套接字连接。
二、注意事项
数据完整性
- 使用`sendall`函数确保所有数据被发送,避免因网络波动导致数据丢失。
- 接收方需根据文件大小读取完整数据,避免读取错误。
字符编码问题
- 传输二进制文件时,需使用二进制模式打开文件(如`fopen(file, "wb")`),避免系统默认的文本编码转换。
跨平台兼容性
- 部分平台(如Windows)的`send`函数可能不保证一次发送所有数据,需使用循环或`sendall`。
三、示例代码(C语言)
以下是一个简单的客户端和服务器端代码示例,演示如何通过TCP传输二进制文件:
客户端代码: ```c include include include include int main() { int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) { perror("socket"); exit(1); } struct sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(8080); inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr); if (connect(sock, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) { perror("connect"); exit(1); } // 发送文件名 const char *filename = "example.bin"; send(sock, filename, strlen(filename), 0); printf("File name sent to server: %sn", filename); // 发送文件内容 FILE *file = fopen(filename, "rb"); if (!file) { perror("fopen"); exit(1); } char buffer; while (fread(buffer, 1, sizeof(buffer), file)) { send(sock, buffer, strlen(buffer), 0); } fclose(file); close(sock); return 0; } ``` 服务器端代码
```c
include include include include int main() { int serverSocket = socket(AF_INET, SOCK_STREAM, 0); if (serverSocket == -1) { perror("socket"); exit(1); } struct sockaddr_in clientAddr; socklen_t addrLen = sizeof(clientAddr); if (bind(serverSocket, (struct sockaddr *)&clientAddr, addrLen) == -1) { perror("bind"); exit(1); } if (listen(serverSocket, 1) == -1) { perror("listen"); exit(1); } int clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &addrLen); if (clientSocket == -1) { perror("accept"); exit(1); } // 接收文件名 char filename; recv(clientSocket, filename, sizeof(filename), 0); printf("File name received: %sn", filename); // 接收文件内容 FILE *file = fopen(filename, "wb"); if (!file) { perror("fopen"); exit(1); } char buffer; while (recv(clientSocket, buffer, sizeof(buffer), 0) > 0) { fwrite(buffer, 1, strlen(buffer), file); } fclose(file); close(clientSocket); close(serverSocket); return 0; } ``` 四、总结 通过以上步骤和注意事项,可以实现可靠的二进制文件传输。若需进一步优化,可添加错误处理、多线程传输或断点续传功能。