使用read和write做一个server和一个client(FTP协议)
Using read and write to do a server and a client (FTP protocol)
我的代码太长了post所以我要总结一下哪里出了问题。
在服务器部分,我在套接字上发送了 3 件事:
一条消息
一个文件的内容
另一个消息
在客户部分,我收到了这些东西,但是:
这首先是在终端打印
第二次写入新文件
最后在终端打印太
但是我的客户卡在阅读上了,我真的不知道为什么。我在这个问题上花了一个小时,所以如果有人能帮助我,那就太好了!
编辑:基本上,我想我的问题是我不知道在服务器上 write
什么来停止客户端上的 read
..是 \n
, [=16=]
.. ?
这是代码的第二部分:
server
void send_content(t_server *s, FILE *fd, int rfd)
{
int len;
char *buff;
write(s->socket, "150 File status okay;" \
"about to open data connection.\n[=11=]", strlen("150 File status okay;about to open data connection.\n[=11=]"));
fseek(fd, 0, SEEK_END);
len = ftell(fd);
buff = malloc(len * sizeof(char));
read(rfd, buff, len);
write(s->socket, buff, len);
write(s->socket, "\n[=11=]", strlen("\n[=11=]"));
write(s->socket, "226 Closing data connection.\n[=11=]", strlen("226 Closing data connection.\n[=11=]"));
free(buff);
}
client
void getfile(t_client *c, char **tab)
{
int ret;
int fd;
int z;
char buff[4096];
z = 0;
read(c->fd, buff, 4096);
write(1, buff, strlen(buff));
if (strlen(buff) < 25)
return ;
fd = creat(tab[1], S_IRUSR | S_IWUSR);
while (z == 0 && (ret = read(c->fd, buff, 4096)) > 0)
{
if (ret < 4096)
z = -1;
write(fd, buff, strlen(buff));
memset(buff, '[=12=]', 4096);
}
read(c->fd, buff, 4096); // Stuck here
write(1, buff, strlen(buff));
close(fd);
}
char buff[4096];
z = 0;
read(c->fd, buff, 4096);
write(1, buff, strlen(buff));
您应该保存调用 read()
的 return 值,以便查明您刚刚收到了多少字节。您可能需要多次调用 read()
才能获得完整的消息。使用 strlen()
来查找接收到的字节数是错误的,因为缓冲区内容未初始化,并且消息的第一个块可能在任何地方被截断,所以你不能指望它是空终止的.
如前所述,您需要像 this 这样的读取功能,以确保您收到
指定的字节数(此函数将循环直到它收到它被告知的字节数)。只需使用此 receivall
方法而不是到处阅读。
对于文件,您通常首先发送文件长度,然后接收文件。
我前段时间做过类似的事情,希望对你有所帮助。这是客户端,它尝试从服务器接收第一个文件长度,然后是文件:
/* create file */
FILE * ptrMyFile = fopen(&filenames[i][0],"wb");
if(NULL == ptrMyFile)
{
printf("Unable to open file \n");
return 1;
}
int size = 0;
int t = 4;
/* first receive file size from server */
/* NOTE: error checking is omitted from code, nevertheless users should stil do some error checking when using this code */
readall(sockfd, (unsigned char*) &size, &t);
/* how many 256 byte chunks are there? */
int div = size / 256;
/* loop to receive each chunk. */
for(int k = 0; k < div; k++)
{
int chunk_size = 256;
/* make sure we receive 256 bytes */
readall(sockfd, buffer, &chunk_size);
/* write to file */
fwrite(buffer, chunk_size, 1, ptrMyFile);
}
/* read the final chunk. */
int whatsleft = size - 256 * div;
readall(sockfd, buffer, &whatsleft);
/* write */
fwrite(buffer, whatsleft, 1, ptrMyFile);
/* close file */
fclose(ptrMyFile);
我把服务器部分留给你。
我的代码太长了post所以我要总结一下哪里出了问题。
在服务器部分,我在套接字上发送了 3 件事:
一条消息
一个文件的内容
另一个消息
在客户部分,我收到了这些东西,但是:
这首先是在终端打印
第二次写入新文件
最后在终端打印太
但是我的客户卡在阅读上了,我真的不知道为什么。我在这个问题上花了一个小时,所以如果有人能帮助我,那就太好了!
编辑:基本上,我想我的问题是我不知道在服务器上 write
什么来停止客户端上的 read
..是 \n
, [=16=]
.. ?
这是代码的第二部分:
server
void send_content(t_server *s, FILE *fd, int rfd)
{
int len;
char *buff;
write(s->socket, "150 File status okay;" \
"about to open data connection.\n[=11=]", strlen("150 File status okay;about to open data connection.\n[=11=]"));
fseek(fd, 0, SEEK_END);
len = ftell(fd);
buff = malloc(len * sizeof(char));
read(rfd, buff, len);
write(s->socket, buff, len);
write(s->socket, "\n[=11=]", strlen("\n[=11=]"));
write(s->socket, "226 Closing data connection.\n[=11=]", strlen("226 Closing data connection.\n[=11=]"));
free(buff);
}
client
void getfile(t_client *c, char **tab)
{
int ret;
int fd;
int z;
char buff[4096];
z = 0;
read(c->fd, buff, 4096);
write(1, buff, strlen(buff));
if (strlen(buff) < 25)
return ;
fd = creat(tab[1], S_IRUSR | S_IWUSR);
while (z == 0 && (ret = read(c->fd, buff, 4096)) > 0)
{
if (ret < 4096)
z = -1;
write(fd, buff, strlen(buff));
memset(buff, '[=12=]', 4096);
}
read(c->fd, buff, 4096); // Stuck here
write(1, buff, strlen(buff));
close(fd);
}
char buff[4096];
z = 0;
read(c->fd, buff, 4096);
write(1, buff, strlen(buff));
您应该保存调用 read()
的 return 值,以便查明您刚刚收到了多少字节。您可能需要多次调用 read()
才能获得完整的消息。使用 strlen()
来查找接收到的字节数是错误的,因为缓冲区内容未初始化,并且消息的第一个块可能在任何地方被截断,所以你不能指望它是空终止的.
如前所述,您需要像 this 这样的读取功能,以确保您收到
指定的字节数(此函数将循环直到它收到它被告知的字节数)。只需使用此 receivall
方法而不是到处阅读。
对于文件,您通常首先发送文件长度,然后接收文件。
我前段时间做过类似的事情,希望对你有所帮助。这是客户端,它尝试从服务器接收第一个文件长度,然后是文件:
/* create file */
FILE * ptrMyFile = fopen(&filenames[i][0],"wb");
if(NULL == ptrMyFile)
{
printf("Unable to open file \n");
return 1;
}
int size = 0;
int t = 4;
/* first receive file size from server */
/* NOTE: error checking is omitted from code, nevertheless users should stil do some error checking when using this code */
readall(sockfd, (unsigned char*) &size, &t);
/* how many 256 byte chunks are there? */
int div = size / 256;
/* loop to receive each chunk. */
for(int k = 0; k < div; k++)
{
int chunk_size = 256;
/* make sure we receive 256 bytes */
readall(sockfd, buffer, &chunk_size);
/* write to file */
fwrite(buffer, chunk_size, 1, ptrMyFile);
}
/* read the final chunk. */
int whatsleft = size - 256 * div;
readall(sockfd, buffer, &whatsleft);
/* write */
fwrite(buffer, whatsleft, 1, ptrMyFile);
/* close file */
fclose(ptrMyFile);
我把服务器部分留给你。