server side code:
dirp=opendir(path);
if(dirp==NULL)
{
strcpy(err,"error:");
strcat(err,strerror(errno));
send(fd,err,sizeof(err),0);
}
else
{
printf("\nstream opened\n");
while((dp=readdir(dirp))!= NULL)
{
r=send(fd,dp->d_name,100,MSG_MORE);
if(r<0)
perror("\nsend:");
printf("\n%s",dp->d_name);
}
}
client:
while(recv(mainsocket,lsbuf,100,0)>0)
{
printf("\n %s",lsbuf);
bzero(lsbuf,sizeof(lsbuf));
}
the server side is printing all the filenames on the standard output,but 开发者_开发问答on the client side the client is not receiving the last filename and program is getting blocked at that point
The problem is with the send
syscall. You call it with MSG_MORE
flag that means the more data will follow and send waits for more data without actually sending. The last chunk of data you should send without this flag. Thus your server side should look like:
dp = readdir(dirp);
if (dp != NULL)
{
/* each time check whether there are more data */
while((dp_next = readdir(dirp))!= NULL)
{
r = send(fd, dp->d_name, 100, MSG_MORE);
if (r < 0) {
perror("\nsend");
}
printf("\n%s",dp->d_name);
dp = dp_next;
}
/* send the last or the only record */
r = send(fd, dp->d_name, 100, 0);
if (r < 0) {
perror("\nsend");
}
}
Another posibility to fix the problem is to close the conenction with the close(fd)
syscall. It send all data in the buffer before closing the connection. It's a less clean, but more simple solution.
Your client prints the newline before lsbuf
, hence everything since the previous newline is lost in your output buffer.
Four solutions:
- use
printf("%s\n", lsbuf);
instead of..."\n %s"...
- use
puts(lsbuf);
, which has the same effect, but is slightly more appropriate - use
fflush(stdout)
after your client loop to flush the output buffer - use unbuffered output, see setvbuf() for details
Note that this problem doesn't seem to be networking-related (although I'd substitute MSG_MORE
with 0
), it's merely a problem with output buffering.
On a sidenote, I strongly suggest to send strlen(dp->d_name) + 1
bytes instead of 100 bytes. This way, you won't send more bytes than necessary, and on the other hand you won't truncate the output if your directory entries happen to be larger than 100 bytes.
Also, neither your client nor your server checks whether send()
/recv()
returns 0
, which means that the connection has been closed by the remote end.
精彩评论