我在c中编写了一个程序,用于从c中的客户端逐行向服务器发送文件。完全传输文件后,我在txt文件中提供了一行endoffile
,用于在服务器中进行字符串比较,以识别文件已结束,然后下一个文件正在传输。必须将下一个文件写入服务器中的另一个文件。但问题是strcmp从未检测到代码中的endoffile
,并且endoffile
从客户端的文件中收到,因为相等的字符串amd继续将下一个文件从客户端写入服务器中的同一文件
char enof[]="endoffile";
...
do
{
rewind(appcrt);
bytes_recieved = recv(pass_arg.connected, recv_data_c, strlen(recv_data_c), 0);
recv_data_c[bytes_recieved-1] = '\0';
fputs(recv_data_c, appcrt);
if(strcmp(enof,recv_data_c) == 0){break;}
}while(check<count);
文本文件:
Necessary data
that is
being transmitted
to be written to the file
endoffile
用于从txt文件读取并发送到服务器的代码:
while (fgets(line, sizeof(line), crt) != NULL)
{
send(sock, line, sizeof(line), 0);
}
我必须在条件中做出哪些更改才能解决问题并且代码从do....while();
循环退出。提前致谢。
操作平台:Linux
Edit1:编辑do....while()
如下:
do
{
rewind(appcrt);
bytes_recieved = recv(pass_arg.connected, recv_data_c, 100, 0);
recv_data_c[bytes_recieved] = '\0';
fputs(recv_data_c, appcrt);
printf("%s-%s",enof,recv_data_c);
//if(strcmp(enof,recv_data_c) == 0){break;}
}while(check<count);
在终端中获得以下输出:
endoffile-file1line1
endoffile-file1line2
endoffile-file1line3
endoffile-file1line4
endoffile-file1line5
endoffile-file1line6
endoffile-endoffile
endoffile-file2line1
endoffile-file2line2
endoffile-file2line3
endoffile-file2line4
endoffile-file2line5
endoffile-file2line6
.
.
.
仍然没有希望。
答案 0 :(得分:2)
即使客户端一次写一行到套接字,这也不是服务器将如何使用它,因为通过套接字传输的数据只是一个字节流。服务器必须读取下一个新行字符,然后进行比较。一个简单的算法会一次读取一个字节,并检查它是否是换行符,如果不是,则将其附加到字符串,直到读取换行符:
/* Read next line. */
memset(line, 0, sizeof(line));
size_t line_len = 0;
while (line_len < sizeof(line) - 1 &&
1 == recv(pass_arg.connected, &line[line_len], 1, 0))
{
if ('\n' == line[line_len]) break;
line_len++;
}
除此之外,代码还存在一些问题:
您需要发送从文件中读取的内容,因为它可能小于sizeof(line)
。变化:
send(sock, line, sizeof(line), 0);
为:
send(sock, line, strlen(line), 0);
并检查send()
的返回值以确定它是否成功。
以下内容不正确,因为它只读取以前读取的最大值(或者如果初始化为空字符串则不会读取任何内容):
bytes_recieved = recv(pass_arg.connected,
recv_data_c, strlen(recv_data_c), 0);
并再次检查返回值,尤其是当返回值用于索引数组时。如果recv()
失败,则返回-1
,这将导致对阵列的界限访问导致未定义的行为。
答案 1 :(得分:1)
while (fgets(line, sizeof(line), crt) != NULL)
{
send(sock, line, sizeof(line), 0);
}
如果该行为空,请不要忘记fgets()
只能读取一个字节。因此,您的send()
调用每次调用都会发送大量未初始化的数据 - 您之前的应用程序的内容或随机内存free()
d。
因此,您的接收程序需要与之比较:
endoffiletten to the file
最后看最后一个字符串。 (假设line
缓冲区开始时充满了ASCII NUL
个字符。)