我想编写一个应用程序来发送带有套接字的文件:
这是我的服务器:
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);
}
我的问题是我的客户端创建了一个文件....但是不要在文件中写入内容!
答案 0 :(得分:7)
为您的代码添加一些错误处理,这可以帮助您追踪问题。另请注意,send()
,recv()
,fread()
和fwrite()
无法保证写入/读取您指定的整个缓冲区,因此您也应考虑到这一点。< / p>
此外,由于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);
}