我刚开始学习套接字编程,我正在尝试使用TCP在客户端和服务器之间发送和接收 . 首先,我从服务器向客户端发送当前目录的大小,客户端正好接收它 . 然后我想直接从服务器发送当前的每个文件名,所以我创建了一个循环来这样做 . 在客户端中,我还有一个循环来接收所有文件名,这些文件名的执行次数与文件(目录大小)一样多 . 问题是,当我打印出循环中收到的内容时,缓冲区为空白 . 我意识到第一个循环接收的字节数为55,其余为0,但缓冲区始终为空 . 这是我的代码片段:
服务器:
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--;
}
}
1 回答
这里的一个问题是发送目录大小的服务器与目录条目和接收它们的客户端之间没有同步 . 换句话说,如果目录包含entry.1,entry.2和entry.3,则客户端可以接收例如entry.1和entry.2entry.3,或entry.1entry.2和entry.3 . 即使这里没有像unicode那样作为罪魁祸首也是如此,正如JVene所建议的那样 .
其他一些事情:
与sizeof()运算符类型使用的
客户端和服务器之间的同步 .
这里的“同步”问题是由于当客户端开始从套接字读取时,服务器已经编写了几个目录条目,因此客户端将它们全部读作一个字符串 . 如果将目录大小写入套接字并从套接字读取,假设缓冲区大小不同,事情就会变得更加混乱;往上看 .
经过一些额外的实验,我提出了似乎有用的代码 . 我确信可以进行改进,还有其他方法,并且代码中没有考虑的情况,例如:如果程序正在运行时目录正在改变该怎么办这只是一段代码的证明,有望帮助您朝着正确的方向前进 .
这里的想法是服务器将目录条目写入由NULL字符分隔的套接字 . 然后将它们用作客户端的分隔符,以区分dir条目 . 请参阅代码中的注释 .
将dir条目写入套接字的服务器代码:
从套接字读取的客户端代码:
希望这有帮助,祝你好运!如果您还有其他问题,请与我们联系 .