从服务器向客户端发送消息

时间:2012-03-13 21:18:53

标签: c sockets

我正在实现简单文件下载程序的服务器端和客户端端。客户端使用get命令从服务器请求文件名,并快速响应服务器响应。当服务器写入套接字时,客户端会读取套接字并打印出缓冲区。在那之后,程序开始不解释我的命令,除非我按两次'Enter'。 (您可以在下面的Shell输出中看到它)

调试后,我发现这是因为缓冲区大小。服务器写入套接字时;如果我使用一个小的缓冲区大小,一切正常。但是如果我使用更大的缓冲区大小(如1024),就会出现问题。我该怎样摆脱这个问题?

#define F_BUFF_SIZE 1024

在服务器端:

/* ... */
if(!strcmp(buffer, "list\n")) {

    char buff[F_BUFF_SIZE];
    bzero(buff, F_BUFF_SIZE);

    pt_ret = pthread_create(&thread_id, NULL, getfiles, (void*) buff);
    pthread_join(thread_id, pt_ret);

    n = write(sock, buff, F_BUFF_SIZE);
/* ... */

在客户端:

/* ... */
char buffer[F_BUFF_SIZE];

bzero(buffer, F_BUFF_SIZE);
n = read(b_sock, buffer, F_BUFF_SIZE - 1);

if (n < 0) {
#ifdef _DEBUG_
    fprintf(stderr, "Error: Could not read from the socket.\n");
#endif
    return 0;
}

fputs(buffer, stdout);
/* ... */

壳牌:

Opening socket: OK!
Connecting: OK!
 # list
client
project1.mk
cs342.workspace
client.c
project1.project
cs342.workspace.session
server
cs342_wsp.mk
server.c
cs342.tags
 # get
 # take
get 
# take
Unknown command.
...

2 个答案:

答案 0 :(得分:1)

@ahmet,你有用的问题引导我研究一下。如果您阅读了一点on this paper,您将更好地了解您正在处理的内容,然后您将能够在您的情况下确定最佳缓冲区大小。

正如您所知,这样的值应该始终是应用程序设置的一部分,因此不要在代码中对这些值进行加扰。

另外,关于如何计算缓冲区大小的here are good advices,希望有所帮助,

答案 1 :(得分:1)

拥有较小的缓冲区大小没有任何魔力,这只是暴露你在其他地方有错误。 Joerg的评论很重要 - 您需要阅读与您编写的数据量相同的数据。我想知道你是如何填充buff的问题。您需要确保没有超出缓冲区的末尾,或者忘记在字符串的末尾添加空终止符。

顺便说一句,重要的是读取大小-1;你这样做是正确的,因为read不会将null终止符附加到字符串。你只需要确定你正在写这个数量,否则会有问题。

你必须在这些方面遇到一些问题 - 这可以解释为什么改变大小可以避免这个问题,因为这样的问题只有在数字完美排列时才会暴露出来。在valgrind中运行程序可能会暴露问题(查找无效的写入错误)。