C-套接字:编程客户端/服务器 – 应用程序以发送文件

我想编写一个应用程序来发送带有套接字的文件:

我的服务器:

void str_server(int sock) { char buf[1025]; const char* filename="test.text"; FILE *file = fopen(filename, "rb"); err_abort("Test"); while (!feof(file)) { int rval = fread(buf, 1, sizeof(buf), file); send(sock, buf, rval, 0); } } 

在这里我的客户:

 void RecvFile(int sock, const char* filename) { int rval; char buf[0x1000]; FILE *file = fopen(filename, "wb"); while ((rval = recv(sock, buf, sizeof(buf), 0)) > 0) { fwrite(buf, 1, rval, file); } close(sock); } 

我的问题是我的客户端创建了一个文件….但是不要在文件中写入内容!

在代码中添加一些error handling,这可以帮助您跟踪问题。 另请注意, send()recv()fread()fwrite()不保证写入/读取您指定的整个缓冲区,因此您也应该考虑到这一点。

此外,由于TCP是字节流,因此服务器需要指示文件何时结束,以便客户端知道何时停止读取。 如果在发送实际文件之前未发送文件大小,则唯一的选择是在传输完成后关闭套接字。

尝试这样的事情:

 int send_all(int sock, const void *buf, int len) { const char *pbuf = (const char *) buf; while (len > 0) { int sent = send(sock, pbuf, len, 0); if (sent < 1) { // if the socket is non-blocking, then check // the socket error for WSAEWOULDBLOCK/EAGAIN // (depending on platform) and if true then // use select() to wait for a small period of // time to see if the socket becomes writable // again before failing the transfer... printf("Can't write to socket"); return -1; } pbuf += sent; len -= sent; } return 0; } void str_server(int sock) { char buf[0x1000]; const char* filename = "test.text"; struct stat s; if (stat(filename, &s) == -1) { printf("Can't get file info"); return; } FILE *file = fopen(filename, "rb"); if (!file) { printf("Can't open file for reading"); return; } // if you need to handle files > 2GB, // be sure to use a 64bit integer, and // a host-to-network function that can // handle 64bit integers... long size = s.st_size; long tmp_size = htonl(size); if (send_all(sock, &tmp_size, sizeof(tmp_size)) == 0) { while (size > 0) { int rval = fread(buf, 1, min(sizeof(buf), size), file); if (rval < 1) { printf("Can't read from file"); break; } if (send_all(sock, buf, rval) == -1) break; size -= rval; } } fclose(file); } 

 int write_all(FILE *file, const void *buf, int len) { const char *pbuf = (const char *) buf; while (len > 0) { int written = fwrite(pbuf, 1, len, file); if (written < 1) { printf("Can't write to file"); return -1; } pbuf += written; len -= written; } return 0; } int read_all(int sock, void *buf, int len) { char *pbuf = (char *) buf; int total = 0; while (len > 0) { int rval = recv(sock, pbuf, len, 0); if (rval < 0) { // if the socket is non-blocking, then check // the socket error for WSAEWOULDBLOCK/EAGAIN // (depending on platform) and if true then // use select() to wait for a small period of // time to see if the socket becomes readable // again before failing the transfer... printf("Can't read from socket"); return -1; } if (rval == 0) { printf("Socket disconnected") return 0; } pbuf += rval; len -= rval; total += rval; } return total; } void RecvFile(int sock, const char* filename) { int rval; char buf[0x1000]; FILE *file = fopen(filename, "wb"); if (!file) { printf("Can't open file for writing"); return; } // if you need to handle files > 2GB, // be sure to use a 64bit integer, and // a network-to-host function that can // handle 64bit integers... long size = 0; if (read_all(sock, &size, sizeof(size)) == 1) { size = ntohl(size); while (size > 0) { rval = read_all(sock, buf, min(sizeof(buf), size)); if (rval < 1) break; if (write_all(file, buf, rval) == -1) break; } } fclose(file); }