【发布时间】:2015-09-15 00:48:52
【问题描述】:
我刚开始学习套接字编程,我正在尝试使用 TCP 在客户端和服务器之间进行发送和接收。首先,我从服务器向客户端发送当前目录的大小,并且客户端可以很好地接收它。然后我想从服务器直接发送当前的每个文件名,所以我创建了一个循环来这样做。在客户端中,我还有一个循环,用于接收与文件(目录大小)一样多次执行的所有文件名。问题是当我打印出循环中收到的内容时,缓冲区是空白的。我意识到第一个循环接收到的字节为 55,其余为 0,但缓冲区始终为空白。这是我的代码 sn-ps:
服务器:
if(strcmp(buffer, "ls-remote") == 0){ //display files from server directory
// get the size of the directory
unsigned long size = htonl(directorySize());
n = send(newsockfd, &size, sizeof(size), 0);
if(n < 0) syserr("can't send to server");
DIR *d = opendir(".");
struct dirent *dir;
if (d)
{
while((dir = readdir(d))!= NULL)
{ memset(&buffer[0], 0, sizeof(buffer)); // clear buffer
strcat(buffer, dir->d_name);
n = send(newsockfd, buffer, strlen(buffer), 0);
if(n < 0) syserr("can't send to server");
}
closedir(d);
}
else{
syserr("Error...could not get files from directory.");
}
}
客户:
if(strcmp(buffer, "ls-remote") == 0){ //display files from server directory
unsigned long size;
n = recv(sockfd, &size, sizeof(uint32_t), 0);// recieve the size of the directory
if(n < 0) syserr("can't receive from server");
size = ntohl(size);
while(size > 0){
memset(&buffer[0], 0, sizeof(buffer)); // clear buffer
n = recv(sockfd, buffer, 255, 0); // recieve directory from server
if(n < 0) syserr("can't send to server");
buffer[strlen(buffer) - 1] = '\0';
printf("recieving: %s\n", buffer); // print directory
size--;
}
}
【问题讨论】:
-
我看不到套接字是如何打开的(是否是 SOCKET_STREAM),或者缓冲区是如何声明的(应该类似于 char buffer[256]; 以便您使用 sizeof(buffer) )。在服务器 sn-p 中,无论消息实际有多长,您都将发送 255 个字节 - 将其限制为名称的 strlen。在客户端 sn-p 上,缓冲区已经归零,因此您不应再次将其归零,如果字符串为零字节,则 strlen(buffer)-1 将是负数,在那里崩溃。使用 n(接收到的字节数)来测量 strlen - 并且知道,除非您知道字符串是零项,否则您不能使用 strlen。
-
感谢您的回复,我正在使用 TCP。我修复了你提到的内容,但我仍然将缓冲区设为空白。我编辑了我的帖子,因为当我从服务器接收时,我意识到循环的第一次迭代接收到的字节数 (n) 是 55,而其他的是 0。
-
套接字是否以 SOCKET_STREAM 形式打开?另外,客户端套接字是否使用 O_NONBLOCK 打开?
-
哦,还有一件重要的事情......你在考虑unicode吗?我相信,您将字符缓冲区视为 ascii,但是如果操作系统返回 unicode 文件名(或某些 MCBS 或其他文件名),那么即使您收到数据,它也会显示为空字符串……您必须转换为 ascii。
-
我正在使用 SOCKET_STREAM 并且客户端套接字未使用 O_NONBLOCK 打开。当我在发送之前在服务器端打印出文件名时,它们打印出来就很好了。
标签: c sockets network-programming