首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

当TCP缓冲区有底据时断开连接,向对端发送的是RST而不是FIN

2013-09-06 
当TCP缓冲区有数据时断开连接,向对端发送的是RST而不是FIN?RT。。比如服务端向客户端发送数据后就read套接字

当TCP缓冲区有数据时断开连接,向对端发送的是RST而不是FIN?
RT。。比如服务端向客户端发送数据后就read套接字,客户端睡眠几秒后(保证服务端的数据已经到缓冲区了)就直接退出,然后服务端的read返回-1,错误信息是 Connection reset by peer。用TCPDUMP观察,发现如果服务端没有发送数据,客户端退出时就发送FIN,否则就发送RST。。请问各位,TCP为什么要这么设计,基于什么考量阿?
[解决办法]
本帖最后由 mymtom 于 2013-08-13 16:09:02 编辑 客户端设置了linger选项,并且将linger时间设置为0


/*-
 * vi:set ts=4 sw=4:
 */
#ifndef lint
static const char rcsid[] = "$Id$";
#endif /* not lint */

/**
 * @file        clnt.c
 * @brief
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
        int fd;
        int ret;
        struct sockaddr_in addr;
        struct linger linger;
        char buf[] = "2013-08-13 14:29:53";

        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        addr.sin_port = htons(12345);

        fd = socket(PF_INET, SOCK_STREAM, 0);

        if (argc == 2 && atoi(argv[1]) > 0) {
                linger.l_onoff = 1;
                linger.l_linger = 0;


                setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger));
        }

        ret = connect(fd, (const struct sockaddr *)&addr, sizeof(addr));
        sleep(1);
        close(fd);

        return 0;
}



/*-
 * vi:set ts=4 sw=4:
 */
#ifndef lint
static const char rcsid[] = "$Id$";
#endif /* not lint */

/**
 * @file        serv.c
 * @brief
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
        int lisnfd;
        int clntfd;
        int ret;
        struct sockaddr_in addr;
        int optval;
        char buf[] = "2013-08-13 14:29:53";
        ssize_t nrecv;

        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
        addr.sin_port = htons(12345);

        lisnfd = socket(PF_INET, SOCK_STREAM, 0);
        optval = 1;
        setsockopt(lisnfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
        ret = bind(lisnfd, (const struct sockaddr *)&addr, sizeof(addr));
        listen(lisnfd, 10);

        clntfd = accept(lisnfd, NULL, NULL);



        send(clntfd, buf, strlen(buf), 0);
        errno = 0;
        nrecv = recv(clntfd, buf, sizeof(buf) - 1, 0);
        if (nrecv < 0)
                perror("recv");

        close(clntfd);
        close(lisnfd);

        return 0;
}



运行结果:
fb82:/home/mymtom/tmp/rst$ ./serv &          
[2] 5119
fb82:/home/mymtom/tmp/rst$ ./clnt 0
[2] - Done                 ./serv 
fb82:/home/mymtom/tmp/rst$ ./serv &
[2] 5121
fb82:/home/mymtom/tmp/rst$ ./clnt 1
recv: Connection reset by peer
[2] - Done                 ./serv 

热点排行