[英]Send a File with socket in C for Linux
我正在编写一个小而简单的服务器(用于Linux工作站的C语言)。
客户端向我的服务器请求文件,我的服务器将此文件询问另一个服务器,该服务器将其发送到我的服务器。
我的服务器在将文件发送到客户端之前不应该收到所有文件但必须发送文件的字节以便它们到达。
这是学校的一项练习,所以我不能脱离这个要求。
我已经实现了下面解释的功能。 问题是客户端收到的是非确定数量的字节,而不是整个文件。
int Recv_and_send_file (int socketa, int socketb, char *buffer, size_t file_size){
size_t n;
ssize_t nread;
ssize_t nwritten;
char c;
for (n=1; n<file_size; n++)
{
nread=recv(socketa, &c, 1, 0);
if (nread == 1)
{
nwritten = send(socketb,&c,1,0);
}
else if (nread == 0)
{
*buffer = 0;
return (-1); /* Errore */
}
else
return (-1); /* Errore */
}
}
*buffer = 0;
return (n);
}
有人可以告诉我哪里错了?
在服务器和客户端上更改值SO_SNDBUF和SO_RCVBUF是一个愚蠢的想法吗?
假设file_size
是您要发送的总字节数,那么for
循环将只发送file_size - 1
个字节。 换句话说,你是一个人。 从0
开始而不是修复此问题:
for (n=0; n<file_size; n++)
{ //..
您捕获send()
的返回值,但不检查它是否成功。
您正在从recv()
处理0
返回值与错误相同。 由于您在从函数返回-1
后没有显示您所执行的操作,因此我不知道这是否会导致您的问题。
send()
和recv()
上的某些错误是“软”的,因为您可以重试这些特定错误的操作。 一个这样的错误是EINTR
,但检查系统上的文档以查看是否还有其他文件。
为了优化性能并简化代码,您可以使用splice()+管道。 Sendfile使您可以在文件描述符之间“转发”数据,而无需将副本复制到用户空间。
您确定已复制了正确的代码吗? 因为它不会编译,所以在最后一个中有一个}与相应的{不匹配}。
另外,您如何知道文件大小? 如果它通过套接字作为整数发送,请记住源和目标机器的可能字节顺序。
无论如何,你一次只读一个字节,你应该这样改进:
编辑:使用缓冲区而不是额外的buff [2048];
int Recv_and_send_file (int socketa, int socketb, char *buffer, size_t file_size){
ssize_t nread;
ssize_t nwritten;
ssize_t bLeft=file_size;
while (bLeft > 0)
{
nread=recv(socketa, buffer, bleft, 0);
if (nread > 0)
{
nwritten = send(socketb, buffer, nread, 0);
bLeft -= nread;
buffer+=nread;
}
else if (nread == 0)
{
// I think this could raise a memory exception, read below
*buffer = 0;
return (-1); /* Errore */
}
else
{
return (-1); /* Errore */
}
}
// If buffer is allocated with file_size bytes this one will raise a memory exception
// *buffer = 0;
return (file_size-bLeft);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.