当前位置: 首页 > 知识库问答 >
问题:

侦听两个不同端口的TCP服务器

支华池
2023-03-14

我有一个监听两个不同端口的TCP服务器。我创建了两个不同的套接字,一个在端口8888上,一个在端口6634上。我监听这些端口,然后我在FD_SET中添加两个套接字,并将它们传递给Select()函数...当套接字准备好读取时,我检查FD_ISSET,看看哪个端口上有消息要读取。

不管怎样,当我连接到8888端口时,构思是成功的,我可以向服务器发送和接收。。。当我在客户端ctrl c时,选择函数再次返回1,现在我的accept()失败了。。。当我在端口6634上做同样的事情时,一切都很好。。。代码在select()处停止,等待套接字准备好读取!

谁能告诉我为什么会这样?

请看附件中的代码

    int main()
    {
        SOCKET          conn_request_skt;   /* socket where connections are accepted */
        char            buf[RBUFLEN], buf1[RBUFLEN];        /* reception buffer */
        uint16_t        lport_n, lport_h, lport_n1, lport_h1;   /* port where the server listens (net/host byte ord resp.) */
        int         bklog = 2;      /* listen backlog */
        SOCKET          s,s1;           
        int         result, n;
        socklen_t addrlen;
        struct sockaddr_in  saddr, caddr;       /* server and client address structures */ 
        int optval,childpid,i; /* flag value for setsockopt */
        int connectcnt; /* number of connection requests */
        fd_set readfds;

        /* Initialize socket API if needed */
        SockStartup();

        /* input server port number */
        lport_h=6634;
        lport_n = htons(lport_h);
        lport_h1=8888;
        lport_n1 = htons(lport_h1);

        /* create the socket */
        printf("Creating first socket\n");
        s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (s == INVALID_SOCKET)
            err_fatal("socket() failed");
        printf("done, socket number %u\n",s);

        /* bind the socket to any local IP address */
        saddr.sin_family      = AF_INET;
        saddr.sin_port        = lport_n;
        saddr.sin_addr.s_addr = INADDR_ANY;
        showAddr("Binding to address first socket", &saddr);
        result = bind(s, (struct sockaddr *) &saddr, sizeof(saddr));
        if (result == -1)
            err_fatal("bind() failed");
        printf("done.\n");

        printf("Creating second socket\n");
        s1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (s1 == INVALID_SOCKET)
            err_fatal("socket() failed");
        printf("done, socket number %u\n",s1);

        /* bind the socket to any local IP address */

        saddr.sin_port=lport_n1;

        showAddr("Binding to address second socket", &saddr);
        result = bind(s1, (struct sockaddr *) &saddr, sizeof(saddr));
        if (result == -1)
            err_fatal("bind() failed");
        printf("done.\n");


        /* listen */
        printf ("Listening at socket %d with backlog = %d \n",s,bklog);
        result = listen(s, bklog);
        if (result == -1)
            err_fatal("listen() failed");
        printf("done.\n");

        printf ("Listening at socket %d with backlog = %d \n",s1,bklog);
        result = listen(s1, bklog);
        if (result == -1)
            err_fatal("listen() failed");
        printf("done.\n");
for (;;)
    {


        FD_ZERO(&readfds);          /* initialize the fd set */
        FD_SET(s, &readfds);
        FD_SET(s1, &readfds); /* add socket fd */
        printf("here \n");

        printf("result bifore select is %d \n", result);
        result=select(s1+1, &readfds, 0, 0, 0);

        printf("result after select is %d \n", result);

        if(result<0)
            {
                err_fatal("select() failed");

            }
        if(result>0)
        {

            if(FD_ISSET(s,&readfds))
            {

                conn_request_skt=s;
                /* accept next connection */
                addrlen = sizeof(struct sockaddr_in);
                s = accept(conn_request_skt, (struct sockaddr *) &caddr, &addrlen);
                if (s == INVALID_SOCKET)
                err_fatal("accept() failed");
                showAddr("Accepted connection from", &caddr);
                printf("new socket: %u\n",s);
                /* serve the client on socket s */
                for (;;)
                {
                    n=recv(s, buf, RBUFLEN-1, 0);
                    if (n < 0)
                    {
                        printf("Read error\n");
                        closesocket(s);
                        printf("Socket %d closed\n", s);
                        break;
                    }
                    else if (n==0)
                    {
                        printf("Connection closed by party on socket %d\n",s);
                        //closesocket(s);
                        break;
                    }
                    else
                    {
                        printf("Received line from socket %03d :\n", s);
                        buf[n]=0;
                        printf("[%s]\n",buf);
                        if(writen(s, buf, n) != n)
                        printf("Write error while replying\n");
                        else
                        printf("Reply sent\n");
                    }   
                }
            }


            if(FD_ISSET(s1,&readfds))
            {
                conn_request_skt=s1;
                /* accept next connection */
                addrlen = sizeof(struct sockaddr_in);
                printf("bifore accept! \n");
                s1 = accept(conn_request_skt, (struct sockaddr *) &caddr, &addrlen);
                if (s1 == INVALID_SOCKET)
                err_fatal("accept() failed");
                showAddr("Accepted connection from", &caddr);
                printf("new socket: %u\n",s1);
                /* serve the client on socket s */
                for (;;)
                {
                    n=recv(s1, buf, RBUFLEN-1, 0);
                    if (n < 0)
                    {
                        printf("Read error\n");
                        closesocket(s1);
                        printf("Socket %d closed\n", s1);
                        break;
                    }
                    else if (n==0)
                    {
                        printf("Connection closed by party on socket %d\n",s1);
                        //closesocket(s);
                        break;
                    }
                    else
                    {
                        printf("Received line from socket %03d :\n", s1);
                        buf[n]=0;
                        printf("[%s]\n",buf);
                        if(writen(s1, buf, n) != n)
                        printf("Write error while replying\n");
                        else
                        printf("Reply sent\n");
                    }   
                }
            }
        }
    }
}

共有2个答案

仉嘉泽
2023-03-14

您正在用accept()调用的结果覆盖套接字变量s1。s1现在包含了你实际读取的套接字的描述符。然后关上插座。但在主循环的下一个过程中,您将检查(现在已关闭)描述符的可读性,这不起作用。

我认为在这种情况下最好不要重用变量。为实际连接套接字使用新变量,以便在s1中保留原始侦听套接字。

梁嘉澍
2023-03-14

第一个侦听器套接字是通过以下方式创建的:

s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

然后通过以下方式接受数据套接字:

 conn_request_skt=s;
 s = accept(conn_request_skt, (struct sockaddr *) &caddr, &addrlen);

看见下一个循环是,当您要在侦听器套接字上进行选择时,s不再保存该套接字,而是保存(闭合的)数据套接字。

解决方案是为侦听器套接字和数据套接字使用不同的变量(conn_request_skt只是混淆了问题)。

 类似资料:
  • 问题内容: 我正在构建一个简单的Java服务器,该服务器使用两个ServerSocket实例同时在两个端口上同时侦听客户端请求。这是服务器的代码: 现在为Client1编码: Client2包含与Client1相同的代码,唯一的区别是它尝试连接到端口3000。现在,我首先使用命令提示符执行Server.java。服务器阻塞时,我打开两个单独的命令提示符,并在一个命令提示符下执行Client1.ja

  • 问题内容: 我需要使用同一端口收听2个不同的多播组。会从和那里听。两个多播组都使用相同的文件,但我无法控制它。 运行程序时,我在每个程序中都接收到两个多播流,即和上广播的数据包。我怀疑问题是由于通用端口引起的。这是我用来订阅多播的代码: 如何在每个程序中过滤特定的多播组? 问题答案: 如果你改变 至 您可能会获得更大的成功。 (如果您更改程序以使用,则可以使其适应未来。)

  • 问题内容: 我有一个GPS跟踪器,可通过GPRS连接将数据连接并发送到已定义的公共服务器:端口。 我可以定义GPS设备的ip:port 我的问题是,我可以只在服务器中打开一个端口并侦听/保存使用PHP接收的数据吗? 谢谢。 问题答案: 编辑/更新2017年8月16日: 用户和库作者@Navarr评论说,他发布了该库的一个新的更新版本,我的原始答案中的代码基于该库。他的github上的新代码的链接在

  • 我已经用重新启动了influxdb,但是没有任何帮助。 我错过了什么? 更新7.11.2016 21:59 更新13.4.2020问题已修复。 这是一个老问题,我不记得我到底是如何解决这个问题的,但我做到了。如果我没记错的话,问题是流入没有加载正确的配置文件,这是我自己当时的愚蠢。可悲的是,我不记得为什么会发生这种事,但我记得这是我自己做的。记住总是正确地阅读文档,并谷歌出它的sht。

  • 我想部署一个tomcat服务器,以便它同时侦听两个端口(都用于超文本传输协议)。 为了确保您正确理解这个需求,我们只有一个服务器实例,但希望侦听HTTP协议的两个端口。例如,任何人都可以使用端口号7080和8080访问部署在我的服务器中的应用程序 有可能做到吗?如果可能,我们如何实现这一点?