Linux中不同进程同一个端口,linux系统实现多个进程监听同一个端口

通过 fork 创建子进程的方式可以实现父子进程监听相同的端口。

方法:在绑定端口号(bind函数)之后,监听端口号之前(listen函数),用fork()函数生成子进程,这样子进程就可以克隆父进程,达到监听同一个端口的目的。

# 代码示例:一主一子

import socket

import select

import sys

import struct

import os

import time

if __name__ == '__main__':

pid = os.getpid()

s1 = socket.socket() # 创建 socket 对象

# host = socket.gethostname() # 获取本地主机名

host = '127.0.0.1'

port1 = 12346 # 设置端口号

# port2 = 12347

# --关键代码--

s1.bind((host, port1))

pid1 = os.fork()

print("我会被主子进程分别执行一次")

# 也可以分别写到分子进程里

s1.listen(5)

# --关键代码--

while True:

if pid1 == 0:

# s1.listen(5)

print("子进程")

socket1, addr1 = s1.accept()

print(addr1)

socket1.send("子进程响应".encode('utf-8'))

socket1.close()

print('结束服务端子进程')

else:

# s1.listen(5)

print("主进程")

socket2, addr2=s1.accept()

print(addr2)

socket2.send("主进程响应".encode('utf-8'))

socket2.close()

print('结束服务端主进程')

# 代码示例:一主多子

import socket

import select

import sys

import struct

import os

import time

if __name__ == '__main__':

pid = os.getpid()

s1 = socket.socket() # 创建 socket 对象

# host = socket.gethostname() # 获取本地主机名

host = '127.0.0.1'

port1 = 12346 # 设置端口号

# port2 = 12347

s1.bind((host, port1))

pid1 = os.fork()

# s1.listen(5)

print("我会被主子进程分别执行一次")

while True:

if pid1 == 0:

s1.listen(5)

print("子进程1")

socket1, addr1 = s1.accept()

print(addr1)

socket1.send("子进程响应1".encode('utf-8'))

socket1.close()

print('结束服务端子进程1')

elif pid1 != 0:

pid2 = os.fork()

if pid2 == 0:

s1.listen(5)

print("子进程2")

socket2, addr2 = s1.accept()

print(addr2)

socket2.send("子进程响应2".encode('utf-8'))

socket2.close()

print('结束服务端子进程2')

else:

s1.listen(5)

print("主进程")

socket2, addr2 = s1.accept()

print(addr2)

socket2.send("主进程响应".encode('utf-8'))

socket2.close()

print('结束服务端主进程')

# 试想下子进程还有子进程的写法和用法

惊群现象

当连接到来时,子进程、父进程都可以 accept, 这就是著名的“惊群”问题(thundering herd problem)。

应用多进程多线程模型

一直疑惑一个应用app如何才能以多进程,多线程的方式运行。对于多线程可能很好理解,我们只要在进程中启用多线程的模式即可。也就是来一个请求,我们就用函数pthread_create()启用一个线程即可。这样我们的应用就可以在单进程,多线程的模式下工作。

一个应用app通常工作在多进程,多线程的模式下,它的效率是最高的。那么我们如何才能做到多进程模式呢?经验告诉我们,如果多次启动一个进程会报错:“Address already in use!"。这是由于bind函数导致的,由于该端口号已经被监听了。

fork原理

fork时,子进程复制一份父进程的资源。然后父子进程分别执行os.fork()之后的程序

子进程中fork函数返回0,父进程中返回子进程的pid

Python的os.fork()是一个会返回两次的函数

通过linux内核的SO_REUSEPORT选项实现多个进程监听相同的端口

# reuseport.py代码

import socket

import os

#xiaorui.cc

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)

s.bind(('0.0.0.0', 1234))

s.listen(1)

while True:

conn, addr = s.accept()

print('Connected to {}'.format(os.getpid()))

data = conn.recv(1024)

conn.send(data)

conn.send(str(os.getpid()))

conn.close()

# 启动多个进程

nohup python reuseport.py &

nohup python reuseport.py &

nohup python reuseport.py &

# 使用nc测试,可以得到随机的一个进程响应

echo "xiaorui" | nc localhost 1234

# 使用socat(nc的增强版)测试,可以得到随机的一个进程响应

echo "ss" | socat - tcp-connect:localhost:1234

linux 系统下开机自动启动oracle 监听和实例 (亲测有效)

[oracle@oracle11g ~]$ dbstartORACLE_HOME_LISTNER is not SET, unable to auto-start Oracle Net Listene ...

linux: 获取监听指定端口的进程PID

在 linux 下经常需要杀死(重启)监听某端口的进程, 因此就写了一个小脚本, 通过 ss 命令获取监听制定端口的进程 PID, 然后通过 kill 命令结束掉进程: #!/bin/sh # set ...

[Linux] 多进程网络编程监听一个端口

SO_REUSEPORT支持多个进程或者线程绑定到同一端口 每个进程可以自己创建socket.bind.listen.accept相同的地址和端口,各自是独立平等的.让多进程监听同一个端口,各个进程中 ...

linux系统中,查看当前系统中,都在监听哪些端口

需求描述: 查看当前系统中都监听着哪些的端口,用netstat命令,在此记录下 操作过程: 1.查看系统中都在监听哪些端口 [root@testvm home]# netstat -ntl Activ ...

Linux中安装Oracle11g后出现监听的问题及解决办法

软件安装: 参考文章: linux安装Oracle11G 错误如下: [oracle@iz2f570bi1k56uz admin]$ lsnrctl start LSNRCTL for Linux: ...

Linux下启动Oracle服务和监听程序步骤

Linux下启动Oracle服务和监听程序启动和关闭步骤整理如下: 1.安装oracle: 2.创建oracle系统用户: 3./home/oracle下面的.bash_profile添加几个环境变量 ...

Linux下的启动oracle服务 启动监听 开放端口操作

尝试登录oracle 使用root用户将没有sqlplus命令 [root@localhost ~]# sqlplus /nolog bash: sqlplus: 未找到命令...     [root ...

获取Windows下某进程监听的TCP/UDP端口

1.在Windows下用CMD netstat命令可以获得当前进程监听端口号的信息,如netstat -ano可以看到IP.port.状态和监听的PID. 那么可以执行CMD这个进程得到监听的端口号信 ...

Linux 使用NC命令永久监听本地端口

感谢: 冰点阳光 Linux可以使用nc命令来测试网络端口是否正常,类似于telnet命令,但也可以用nc命令来监听本地端口,支持TCP.UDP协议,当我们测试NTP服务网络策略是否正常时,可以使用到 ...

随机推荐

NOIP 考前 数论复习

POJ 2891 x=r1 (mod a1) x=r2 (mod a2) x=a1*x+r1,x=a2*y+r2; a1*x-a2*y=r2-r1; 用Extend_Gcd求出m1*x+m2*y=d; ...

mysql数据库字符集的设置

my.ini文件中clinet和mysqld中的写法不一样,要注意  [client]   port=3306   default-character-set=utf8      [mysqld]   ...

csuoj 1503: 点到圆弧的距离

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1503 1503: 点到圆弧的距离 时间限制: 1 Sec  内存限制: 128 MB  Speci ...

(1)java虚拟机概念和结构图

java虚拟机解构图一 java虚拟机解构图二 java虚拟机结构图三 [1]类加载系统        --->负责从文件系统或网络中加载class信息,存放至方法区的内存空间[2]java堆  ...

深入了解epoll (转)

一. 介绍 Epoll 是一种高效的管理socket的模型,相对于select和poll来说具有更高的效率和易用性.传统的select以及poll的效率会因为 socket数量的线形递增而导致呈二次乃 ...

candy(动态规划)

题目描述 There are N children standing in a line. Each child is assigned a rating value. You are giving ...

Java六大必须理解的问题

Java六大必须理解的问题 对于这个系列里的问题,每个学Java的人都应该搞懂.当然,如果只是学Java玩玩就无所谓了.如果你认为自己已经超越初学者了,却不很懂这些问题,请将你自己重归初学者行列.内容 ...

纯CSS打造萌萌哒大白

HTML部分:

BeautifulSoup4----利用find_all和get方法来获取信息

中文文档 官方教学网页源码:

Page title

jQuery设置内容和属性方

何问起 hovertree.com 设置内容 - text().html() 以及 val()text() - 设置或返回所选元素的文本内容html() - 设置或返回所选元素的内容(包括 HTML ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值