我正在实现一个简单文件下载程序的服务器端和客户端。客户端通过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.
...
最佳答案
拥有较小的缓冲区大小并没有什么神奇之处,这只是暴露了您在其他地方有错误。 Joerg 的评论很重要——您需要读取与写入相同数量的数据。我想知道你填充buff的方式是否也有问题。您需要确保没有超出缓冲区的末尾,或者忘记在字符串的末尾添加空终止符。
顺便说一句,读取大小很重要 - 1;你这样做是正确的,因为 read 不会将空终止符附加到字符串中。您只需要确保您写的是该金额,否则可能会出现问题。
您一定在这些方面遇到了一些问题 - 这可以解释为什么更改大小可以避免该问题,因为只有当数字完美排列时才会暴露此类问题。在 valgrind 中运行程序可能会暴露该问题(查找无效写入错误)。
关于c - 从服务器向客户端发送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9692355/