Betflop Asked:2022-04-06 16:01:00 +0800 CST2022-04-06 16:01:00 +0800 CST 2022-04-06 16:01:00 +0800 CST 一个开放端口和一个套接字防火墙如何工作? 772 我无法弄清楚防火墙是如何工作的,等等。带开口插座。假设我们打开了 80 端口,在连接时,会创建一个新的套接字,该套接字已经有一个新的一堆,例如 x.x.x.x: 1234 客户端和 x.x.x.x: 8081 服务器,将来客户端和服务器将直接向这些端口发送请求,正确的?但是在服务器上,我们只开放了 80 端口,它是如何工作的呢? сокет 1 个回答 Voted Best Answer S.H. 2022-04-06T16:08:24+08:002022-04-06T16:08:24+08:00 我觉得你自己有点糊涂了。 这是问题的一部分:“在连接时,会创建一个新的套接字,该套接字已经有一个新的捆绑包,例如 x.x.x.x: 1234 客户端和 x.x.x.x: 8081 服务器” 你为什么这么认为? 处于“关闭”状态的 TCP 套接字 - 在逻辑级别 - 四个数字的组合:“客户端 IP、客户端端口、服务器 IP、服务器端口”。 当连接到 80 端口时,服务器端口将是 80 端口。 如果您不是这种情况,请检查它,这意味着您打开了另一个端口。 现在 - 一个小题外话,将帮助您了解端口是如何工作的。 问题的底部是一个简单的“服务器”,它侦听端口 1080,并为每个连接的客户端发送此连接的处理到 doit () 过程(在一个单独的过程中) 现在让我们看看连接是如何创建的。 当服务器运行时,它与字符串匹配int connfd=accept(listenfd, (struct sockaddr*)&clientaddr, &addrlen);。 要启动服务器以“侦听套接字”——您需要已经知道 TCP 连接的“一半”——服务器地址和服务器端口。 服务器将挂在这条线上,直到客户端连接到它。 一旦客户端加入,accept 过程就会返回一个结构,该结构已经成为一个“完整”的 TCP 连接,并且客户端部分被添加到服务器部分 - 客户端地址和用于建立连接的客户端端口。 接下来,进程被FORKed,在新创建的进程中,端口被完全像处理文件一样处理——此时我们已经有了一个文件描述符fd。 当进程完成处理时,它会关闭“文件”。内核将负责其余的工作。 创建服务器套接字时作为“队列长度”传递的值“5”是一个数字,它告诉有多少客户端连接可以排队等待处理(这将对应于客户端快速连接和新进程的情况对他们来说处理很慢) 因此,同时连接的客户端的数量仅受服务器资源的限制,而不受连接架构的限制。 再一次:启动客户端通过相同的 IP 连接。但随后客户端操作系统将在客户端为它们提供不同的端口。因此服务器将能够“区分”它们。更不用说从不同 IP 连接的客户端了。 // server int main(){ int listenfd = socket(AF_INET,SOCK_STREAM,0); //серверный сокет struct sockaddr_in server_addr ; server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(1080); if (bind(listenfd, (struct sockaddr*)&server_addr, sizeof(server_addr))<0){ // параметры сокета printf ("Error in bind\n"); return 0; } if (listen (listenfd,5)<0) { // 5 - глубина очереди printf ("Error in listen\n"); return 0; } printf ("Server started!\n" ); for (;;){ struct sockaddr_in clientaddr; socklen_t addrlen = sizeof(clientaddr); int connfd=accept(listenfd, (struct sockaddr*)&clientaddr, &addrlen); printf ("Connection with connfd=%d from port=%d accepted!\n", connfd, clientaddr.sin_port); pid_t pid; if ((pid=fork())==0){ // fork раздваивает процесс close(listenfd); doit (connfd, clientaddr.sin_port); close (connfd); _exit(0); } close(connfd); } }
我觉得你自己有点糊涂了。
这是问题的一部分:“在连接时,会创建一个新的套接字,该套接字已经有一个新的捆绑包,例如 x.x.x.x: 1234 客户端和 x.x.x.x: 8081 服务器”
你为什么这么认为?
处于“关闭”状态的 TCP 套接字 - 在逻辑级别 - 四个数字的组合:“客户端 IP、客户端端口、服务器 IP、服务器端口”。
当连接到 80 端口时,服务器端口将是 80 端口。
如果您不是这种情况,请检查它,这意味着您打开了另一个端口。
现在 - 一个小题外话,将帮助您了解端口是如何工作的。
问题的底部是一个简单的“服务器”,它侦听端口 1080,并为每个连接的客户端发送此连接的处理到 doit () 过程(在一个单独的过程中)
现在让我们看看连接是如何创建的。
当服务器运行时,它与字符串匹配
int connfd=accept(listenfd, (struct sockaddr*)&clientaddr, &addrlen);
。要启动服务器以“侦听套接字”——您需要已经知道 TCP 连接的“一半”——服务器地址和服务器端口。
服务器将挂在这条线上,直到客户端连接到它。
一旦客户端加入,accept 过程就会返回一个结构,该结构已经成为一个“完整”的 TCP 连接,并且客户端部分被添加到服务器部分 - 客户端地址和用于建立连接的客户端端口。
接下来,进程被FORKed,在新创建的进程中,端口被完全像处理文件一样处理——此时我们已经有了一个文件描述符fd。
当进程完成处理时,它会关闭“文件”。内核将负责其余的工作。
创建服务器套接字时作为“队列长度”传递的值“5”是一个数字,它告诉有多少客户端连接可以排队等待处理(这将对应于客户端快速连接和新进程的情况对他们来说处理很慢)
因此,同时连接的客户端的数量仅受服务器资源的限制,而不受连接架构的限制。
再一次:启动客户端通过相同的 IP 连接。但随后客户端操作系统将在客户端为它们提供不同的端口。因此服务器将能够“区分”它们。更不用说从不同 IP 连接的客户端了。