【发布时间】:2012-02-07 12:09:53
【问题描述】:
我正在开发一个二进制文件传输程序,其中客户端必须将文件上传到服务器。对于这种情况,我需要先发送文件名,然后再发送文件内容。但这对我来说是不可行的。
让我们看看代码:
// Client-side code to send file name
void sendFileName(
int sd, /*Socket Descriptor*/
char *fname) /*Array Containing the file name */
{
int n , byteswritten=0 , written ;
char buffer[1024];
strcpy(buffer , fname);
n=strlen(buffer);
while (byteswritten<n)
{
written=write(sd , buffer+byteswritten,(n-byteswritten));
byteswritten+=written;
}
printf("File name : %s sent to server \n",buffer);
}
在这段代码中,我通过套接字写入文件名,服务器将从套接字读取名称,如下所示:
// Server-side code to read file name from client
while ((n = read((int)connfd, (fname + pointer), 1024)) > 0)
{
pointer=pointer+n;
}
好吧,问题是我必须在发送文件名后关闭客户端的写入端,这将是服务器端代码停止从服务器读取的 FIN 段。
如果我像这样关闭读取端:
shutdown(sd,SHUT_WR); //Closing write end at client side
如何通过套接字将文件内容写入(即发送)到服务器,以便它可以从套接字读取?
注意:我所做的是将文件名附加到来自客户端的文件内容,并在内容中添加一个特殊字符(用于通知文件名结束),然后是文件内容。
在客户端,
void readWriteFile(
int sd, /*Socket Descriptor */
int fd, /*File Descriptot */
char *fname) /*File Name */
{
char buffer[1050];
int n;
int len = 0;
char *tmp = (char *)malloc(sizeof (char) * (strlen(fname) + 2));
strcpy(tmp, fname); //Copying the file name with tmp
strcat(tmp, "/"); //Appending '/' to tmp
len = strlen(tmp);
memset(buffer, '\0', sizeof (buffer));
strcpy(buffer, tmp); //Now copying the tmp value to buffer
while ((n = read(fd, buffer + len, 1024)) > 0)
{
if (write(sd, buffer, n) != n)
{
printf("File write Error \n");
exit(0);
}
len = 0;
}
printf("File sent successfully \n");
}
在服务器端,
char fname[50], buffer[1024];
int n, fd;
int i;
int start = 0;
while ((n = read((int)connfd, buffer, 1024)) > 0) // Reading from socket
{
if (!start)
{
/* This 'if' loop will executed almost once i.e. until
getting the file name */
for (i = 0; i < 1024; i++)
{
/* Since '/' is the termination character for file name */
if (buffer[i] == '/')
{
start = 1; // Got the file name
break;
}
fname[i] = buffer[i]; //Storing the file name in fname
}
fname[i] = '\0';
/* Creating the file in the server side */
fd = open(fname, O_WRONLY | O_CREAT, S_IRWXU);
if (fd < 0)
{
perror("File error");
exit(0);
}
/* Here writing the buffer content to the file after
the (buffer+i+1), because after this address only, we
can get the original file content */
write(fd, buffer + i + 1, n);
}
else
{
write(fd, buffer, n);
}
}
printf("%s received successful \n", fname);
此代码适用于图像、可执行文件和文本文件。但是,如果我发送任何音频文件,它就不会在服务器端播放。大小仍然是大小。但我想知道为什么音频文件会发生这种情况。逻辑有什么问题吗?我还没有试用视频文件。
【问题讨论】:
-
注意
written的返回值在非常普通的情况下可能是-l,例如errno是EGAIN或EINTR。这会给你的逻辑带来麻烦。 -
“但这对我来说不可行。”如果它不可行,为什么还要问呢?听起来你已经放弃了。
标签: c sockets client-server shutdown file-transfer