3

我已经用 c 编写了一个程序,可以将文件从 c 中的客户端逐行发送到服务器。文件传输完成后,我endoffile在txt文件中提供了一行,用于在服务器中进行字符串比较,以识别文件结束,接下来正在传输下一个文件。下一个文件必须写入服务器中的另一个文件。但问题是 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
.
.
.

还是没有希望。

4

2 回答 2

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,这将导致对数组的越界访问导致未定义的行为。

于 2012-06-21T22:53:51.747 回答
1
while (fgets(line, sizeof(line), crt) != NULL)
{
    send(sock, line, sizeof(line), 0);
}

不要忘记fgets(),如果该行是空白的,它可能只读取一个字节。因此,您的send()呼叫在每次呼叫时都会发送大量未初始化的数据——无论是前几行的内容还是free()您的应用程序之前的随机内存 d。

因此,您的接收程序需要比较:

endoffiletten to the file

终于看到最后的字符串了。(假设line缓冲区一开始就充满了 ASCIINUL字符。)

于 2012-06-21T22:51:29.040 回答