一 tcp1
server.py
#coding:utf8 #首行编码声明否则可能报错 pycharamSetting_fileEncode均设UTF8
import time,socket,os,psutil,multiprocessing
def server_socket(): #localhost="localhost"/"127.0.0.1"/本机局域网IP(注意:不同于127)
s = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
localhost,port,max_client_connect_num ="127.0.0.1",9999, 5
s.bind( (localhost, port) )
s.listen( max_client_connect_num )
print(f"服务器启动 浏览器也可访问localhost:9999 {s}")
print("ipv4:%s"%s.family,"tcp:{}".format(s.type),s.getsockname())
p=multiprocessing.current_process()
pr = psutil.Process(p.pid)
print(f"[父进程]{pr.ppid()}\n{ psutil.Process( pr.ppid() ) }")
print(f"[本进程]{pr.pid} {os.getpid()}\n{pr}")
print(f"[子进程]控制台宿主进程 {pr.children()[0].pid}")
print(pr.children())
message = "<html><body>I’m server socket\r\nmessages for you\r\n</body></html>"
while True:
server_client_socket,client_addr=s.accept()
print(f"【{time.strftime('%Y-%M-%d %X')}】监听到客户端{client_addr}连接:{server_client_socket}")
server_client_socket.send(message.encode("utf8"))
server_client_socket.close()
if __name__ == '__main__':
server_socket()
client.py
#coding:utf8 #客户端程序 a2.py(client.py)
import socket,os,subprocess,multiprocessing
def demo0(): #服务器程序均要启动时测试
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host, port = "localhost", 9999
client_socket.connect((host, port))
msg = client_socket.recv(1024)
client_socket.close()
print(msg.decode('utf-8'),msg)
def demo1(port:int=9999)->None: #服务器启动 检测到9999端口 os.system有中文乱码?
cmd1="netstat -h"
print(f"【{cmd1}】pycharm中文乱码 FileSettingEditor_FileEncodings/GlobalEncoding UTF-8改GBK")
os.system(command=cmd1)#直接显示执行结果 使用完后再改为UTF8 【CMD】netstat -h ; netstat -ano ;
cmd2="netstat -ano | findstr {}".format(port)
print(f"【2】{cmd2}\t最后一个数字为进程pid")
os.system(command=cmd2)
def demo2(port:int=9999)->None: #os.popen中文乱码 运行服务器
#print( os.popen(" netstat -h " ,mode="r").read() )
print("【1】",os.popen(cmd="netstat -ano | findstr %s" % port,mode="r").read())
try:
pid=os.popen(cmd="netstat -ano | findstr %s" % port,mode="r").read().split(" ")[-1].strip()
if pid:
print("【2-1】服务器pid=",pid,os.popen(f"tasklist | findstr {pid}").read())
print("【2-2】\n", os.popen(f"tasklist | findstr python").read())
print("【2-3】\n", os.popen(f"tasklist | findstr pycharm").read())
pipe=os.popen( f"taskkill /pid {pid} /f /t" )
print(pipe.read())
except:
print(f"不存在端口为{port}结论:服务器程序启动有三个进程 pycharm父 python本 console子")
def _get_subprocess_Popen():
return subprocess.Popen("cmd.exe", stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def demo3(port:int=9999)->None:
commands=["echo %cd%","cd","hostname"]
p=_get_subprocess_Popen()
for cmd in commands:
p.stdin.write( (cmd+"\n").encode("utf8"))
p.stdin.close() #【标准输入】关闭才能读取【标准输出】
print(p.stdout.read().decode("gbk"))
p.stdout.close()
p.stderr.close() #关闭了 可以重新启动了没有此方法?
print("\n"+"----"*20+"\n")
p = _get_subprocess_Popen()
cmd1=f"netstat -ano |findstr {port}\n"
p.stdin.write(cmd1.encode())
p.stdin.close()
data=p.stdout.read().decode("gbk").strip()
print("【1】",data)
index=data.find("LISTENING")
pid0=data[index:index+21]
print("【2】",pid0,f"pid={pid0.split(' ')[-1].strip()}")
process < thread
#coding:utf8 # 一个程序 实现 服务器和客户端的功能 线程优于进程 进程占系统资源
import os,re,socket,threading,multiprocessing,time
def server():
s = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
s.bind(("127.0.0.1", 9999))
s.listen(5)
while True:
server_client_socket, client_addr = s.accept()
print(f"【{time.strftime('%Y-%M-%d %X')}】监听到客户端{client_addr}连接:{server_client_socket}")
server_client_socket.send("I'am server\r\nhow are you\r\n".encode())
server_client_socket.close()
def client(num):
c=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
c.connect( ("127.0.0.1", 9999) )
print(f"【c{num}】接收信息",c.recv(1024).decode('utf-8').strip(),threading.current_thread().name)
c.close()
class Monitor:
@classmethod
def multiprocessing_handle(cls): #进程方法启动服务器程序
s_process=multiprocessing.Process( target=server)
s_process.start()
time.sleep(2) #确保服务器进程先运行
for num in range(1,6):
multiprocessing.Process(target=client,args=(num,),name="client-%s"%num).start()
time.sleep(6)
s_process.terminate() #服务器已停止 netstat -ano | findstr 9999(隔时执行 端口占用但无pid)
@classmethod
def threading_handle(cls): # 线程启动程序=产生新的服务器或客户端的进程
st = threading.Thread(target=server)
st.start()
time.sleep(2)
for num in range(1,3):
client_process=threading.Thread(target=client,args=(num,),name="client-%s"%num)
client_process.start()
time.sleep(3)
del st # 不起作用
pipe=os.popen("netstat -ano | findstr 9999")
data=pipe.read()
print(data, )
pids=re.findall(r"LISTENING\s+\d+",data)
pid=re.findall(r"LISTENING\s+(\d+)",data)[0]
print(pids,pid)
#f"taskkill /pid {pid} /f /t"
pip=os.popen(f"taskkill /pid {pid} /f")
print("若无信息,关闭正常: ",pip.read())
if __name__ == '__main__':
Monitor.threading_handle()
二. tcp2
(一) utils.py
#coding:utf8
import socket
"""
项目/utils.py python如何抓取 网卡的包? 以后再完善
本例 服务器只能按照先后的顺序处理客户端的通信
"""
def get_tcp_server_socket(port:int=9999)->socket.socket:
print("【socket1】",socket.AF_INET,socket.SOCK_STREAM)
print("【socket2】",socket.SOL_SOCKET,socket.SO_REUSEADDR)
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind( ("localhost",port) )
server.listen() # 设5 10 或不设置参数 开启线程或进程同时接受服务
return server
(二)server.py 使用class方法
#coding:utf8
import time
from utils import get_tcp_server_socket
CODING="utf-8"
BUFSIZ = 1024
class TcpServer():
def __init__(self):
self.server=get_tcp_server_socket(port=9999)
print("---- 服务器已启动 监听所有客户端连接----")
self.handle_clients()
def handle_clients(self):
while True:
try:
conn, addr = self.server.accept()
print("链接的客户端:", addr)
self.do_one_client(conn)
except:
print("服务器报错")
break
self.server.close()
#加一个trycatch 类似"褐桃色"为底的警告提示
def do_one_client(self,conn):
while True:
try:
data = conn.recv(BUFSIZ) # 读取已链接客户的发送的消息
except Exception:
print("断开的客户端", conn.getpeername())
break
print("客户端发送的内容:", data.decode(CODING))
if not data:
break
msg = time.strftime("%Y-%m-%d %X") # 获取结构化时间戳
msg1 = '[%s]: %s' % (msg, data.decode(CODING))
conn.send(msg1.encode(CODING)) # 发送消息给已链接客户端
conn.close() # 关闭客户端链接
if __name__ == '__main__':
print("--【服务器只接收一个客户端服务,其他客户端需要等待】--")
TcpServer() # 此处的类的使用 = 函数
(三)client.py
#coding:utf8
from socket import *
class TcpClient():
ADDR = HOST, PORT ="localhost", 9999
CODING, BUFSIZ = "utf-8", 1024
def __init__(self):
self.client = socket(AF_INET, SOCK_STREAM)
self.client.connect( TcpClient.ADDR )
self.handle()
self.client.close()
def handle(self):
while True:
try:
data = input('>>').strip()
if not data:
print("输入不能为空,请重新输入...")
continue
if data.lower() in ["exit","quit"]:
print("客户端退出")
break
self.client.send(data.encode( self.CODING ))
data = self.client.recv( TcpClient.BUFSIZ )
if not data:
break
print(data.decode( self.CODING ))
except:
print("客户端出现未知异常...")
pass
if __name__ == '__main__':
TcpClient()
三.tcp3
import socket
HOST, PORT, CLIENT_MAX_CONNENT = "localhost", 9999, 5
class ServerTCP_dialog:
def __init__(self):
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind( (HOST,PORT) )
server.listen(CLIENT_MAX_CONNENT) ##监听自已的端口 是否有客户端进入
self.s=server
print("服务器启动..")
self.single_client_conn() ##生成 self.conn
while True:
try:
self.server_receive() ##生成 self.data
if not self.data:
break #客户端断开退出
self.server_send()
except:
break #服务器异常退出
self.conn.close()
self.s.close()
def single_client_conn(self):
self.conn,addr=self.s.accept() #3次成功握手获得连接对象
print(self.conn,addr)
def server_receive(self):
self.data = self.conn.recv(1024).decode()
print("【fromClient】%s"%self.data)
#客户端断开后,接收最后1条空串
def server_send(self):
dialog = {
'who are you': 'I am xiaoli',
"你是谁?": "我是小李",
'how old are you this year?': 'twenty-one',
"你多大": "二十一岁",
'where are you come from': 'GuangDong!',
"你来自哪里": "广东",
"what do you do?": "I'm here to do business",
"你做什么": "经商"
}
data=dialog.get( self.data.strip() ,"i don't know")
self.conn.sendall(data.encode())
#send 和 sendall的 区别? sendall 发送所有客户端
if __name__ == '__main__':
ServerTCP_dialog()
import socket,sys,time
host,port="localhost",9999
class ClientTCP_dialog:
def __init__(self):
self.client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
self.client.connect( (host,port) )
print("连接服务器的信息:",self.client.getpeername())
print("本地ip端口:",self.client.getsockname())
except:
print('服务端已经断开连接,程序退出...')
sys.exit()
try:
self.send_receive_message()
except:
print("服务器异常...")
def send_receive_message(self):
ms=['who are you', '你是谁?', 'how old are you this year?',
'你多大', 'where are you come from', '你来自哪里',
'what do you do?', '你做什么']
for m in ms:
print(m)
self.client.send(m.encode())
time.sleep(0.5)
print(f"【from服务端】{ self.client.recv(1024).decode() }")
time.sleep(0.5)
print("ByeBye!")
self.client.send( "ByeBye!".encode() )
print("【from服务端】%s"% self.client.recv(1024).decode() )
self.client.close()
if __name__ == '__main__':
ClientTCP_dialog()
四 UDP1
#coding:utf8
"""
server.py(bind功能 无listen方法 但其实有监听功能)
UDP不会产生粘包现象 接收长度不够时 直接丢弃 但windows可能
(1)绑ip端口
(2)接收无需客户端ip端口但会获客户端ip端口
(3)向客户端发送
"""
import socket #pycharmCode_optimize Imports(自动优化导包)
import time
class UdpServer():
def __init__(self):
self.s=socket.socket(family=socket.AF_INET,type=socket.SOCK_DGRAM)
self.s.bind( ("localhost",9999) )
print("【UDP】启动 不会有粘包 接收长度不够时直接丢弃但windows可能报错")
self.start()
def start(self):
while True:
try:
data_bytes,addr=self.s.recvfrom(1024) #data_bytes可以变大写?
print("【服务器接收客户端的元组】",data_bytes,addr)
t=time.strftime("%Y-%m-%d %X")
msg=f"【from server】{t} ".encode() + data_bytes.upper()
self.s.sendto(msg,addr)
except:
print("【UDP】异常")
break
self.s.close()
if __name__ == '__main__':
UdpServer()
# coding:utf8
import socket
def udpclient():
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
print("[客户端]启动...",client)
while True:
try:
message = input(">>: ").strip()
if not message:
continue
if message in ["exit()","quit()"]:
break
addr=("127.0.0.1", 9999) # 服务端IP端口地址
client.sendto( message.encode("utf-8"), addr )
print("[客户端]addr信息:",client.getsockname())
data,serverAddr=client.recvfrom( 1024 ) #1024 6
print(data.decode(),serverAddr)
except: # 1024可以改小一些 如 6
print("[客户端]异常退出 如【windows接收长度不够报错】")
break
client.close()
udpclient()
# coding:utf8
import time,socket
def get_udp_client()->( socket.socket , tuple ):
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
msg="[client1]来信息".encode()
addr=("127.0.0.1", 9999) #不知道服务是否在线 我随意发信息
client.sendto( msg, addr )
time.sleep(1)
return client,client.getsockname()
def main():
c1, addr1 = get_udp_client()
c2, addr2 = get_udp_client()
print(c1, addr1)
print(c2, addr2)
try:
c1.sendto( "[client1] hello, client2".encode(),addr2 )
time.sleep(1)
data_bytes,addr2=c2.recvfrom(1024)
print(data_bytes,addr2)
except Exception as e:
print("两个客户端之间不能直接通信 需通过服务器转发 报错")
print(e)
time.sleep(2)
c1.close()
c2.close()
if __name__ == '__main__':
main()