【发布时间】:2020-12-05 04:58:11
【问题描述】:
我已经使用 linux tcp 套接字编写了服务器客户端程序。
客户端通过以下方式向服务器请求当前目录文件列表 发送 ls 命令
server replies all the list of files in server dir.
I was testing it for more files in server working dir.
server response format in the buffer
file/dir [tab] file_name [tab] file_change_time
for each 1000 files to client.
服务器发送代码:
#define BUFSIZE 1400
void lsfun(node_t *pclient)
{
DIR *directory;
int status;
int cpylen = 0;
int msglen = 0;
unsigned int tt_count = 0;
unsigned int no_files = 0;
unsigned int no_sends = 0;
int clientfd = *(pclient->client_socket);
char *filectime;
char *buffer = malloc(BUFSIZE * sizeof(char));
char *tmp = malloc(BUFSIZE * sizeof(char));
char ending[] = "#####";
struct dirent *dir;
struct stat type;
pthread_mutex_lock(&lock);
chdir(pclient->pwd);
directory = opendir(".");
pthread_mutex_unlock(&lock);
if(tmp == NULL || buffer == NULL)
printf("malloc error for client conn:%d\n", clientfd);
if(directory)
{
while((dir = readdir(directory)) != NULL)
{
if(!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, ".."))
continue;
status = stat(dir->d_name, &type);
if(status == 0)
{
filectime = ctime(&type.st_ctime);
if(dir->d_type != DT_REG)
cpylen = snprintf(tmp, BUFSIZE, "dir\t%s\t%s", dir->d_name, filectime);
else
cpylen = snprintf(tmp, BUFSIZE, "file\t%s\t%s", dir->d_name, filectime);
tmp[cpylen] = 0;
if((cpylen + msglen) < BUFSIZE)
{
strlcpy(buffer + msglen, tmp, cpylen);
msglen += cpylen;
no_files += 1;
}
else
{
tt_count += msglen;
printf("%s", buffer);
fflush(stdout);
send(clientfd, buffer, strlen(buffer), 0);
memset(buffer, 0, BUFSIZE + 5);
snprintf(buffer, cpylen, "%s", tmp);
msglen = cpylen;
cpylen = 0;
no_files += 1;
no_sends += 1;
}
}
else
{
cpylen = snprintf(buffer + msglen, BUFSIZE, "%s%s\n", "file stat error:", dir->d_name);
msglen += cpylen;
}
memset(tmp, 0, BUFSIZE);
}
}
cpylen = strlen(buffer);
if(msglen == cpylen)
send(clientfd, buffer, strlen(buffer), 0);
send(clientfd, ending, strlen(ending), 0); //sending msg ending for client read to close
printf("\nlssize :%d\tnofile:%d, msglen:%d\tcpylen:%d\tno_sends:%d\n", tt_count + msglen, no_files, msglen, cpylen, no_sends);
free(tmp);
free(buffer);
closedir(directory);
}
客户端接收代码:
#define BUFSIZE 1400
while(true)
{
msgsize = read(socketfd, buffer, BUFSIZE);
buffer[msgsize] = 0;
snprintf(ending, 6, "%s", buffer + (strlen(buffer) - 5));
if(strcmp(ending, "#####") == 0)
{
buffer[strlen(buffer) - 5] = 0;
if(buffer[strlen(buffer) - 1] == '\n')
printf("%s", buffer);
else
printf("%s\n", buffer);
fflush(stdout);
break;
}
else
{
printf("%s", buffer);
memset(buffer, 0, BUFSIZE);
}
}
服务器重放调试打印:
lssize :19931 nofile:501, msglen:437 cpylen:39 no_sends:14
为什么我只收到两个数据包而不是来自
的 14 个数据包
每个大约 1400 字节的服务器数据包?
错在哪里?
也欢迎任何代码改进建议。
【问题讨论】:
-
如果您在代码中添加 [c] 标签,您还将获得更多的读者。资深读者在 S.O.只读标记有他们感兴趣的领域的问题。祝你好运。
-
您必须正确、完整地处理 send/recv 等系统调用返回的结果
-
@Sekhar '客户端将始终只从服务器接收 1400 字节',如果您使用 TCP 字节流,则不能这么说。
-
'tmp[cpylen] = 0;'似乎毫无意义,因为 strlcpy 不会复制它,并且是潜在的(尽管不太可能)OOB 写入。
-
bug 太多了。您需要在修复丢失的返回值处理等后测试和调试此代码。
标签: c linux sockets tcp tcpserver