最近学习python 的socket模块,想实现两台不同主机的聊天
通信主机1的配置:
- win10
- python 3.6
- 通信ip:在cmd运行ipconfig后 无线局域网WLAN处的IPv4
通信主机2的配置:
- win10
- python 3.8
- 通信ip:在cmd运行ipconfig后 无线局域网WLAN处的IPv4
实现效果:主机1、2基于UDP的聊天
- 主机1、2均为双工,运行开始时双方均开启发送和接收两个线程
- 主机1发消息结束[主机1发送消息的线程结束],主机2不再接收[主机2的接收线程结束];
此时主机1还可以接收2的消息;
此时若主机2发消息结束[主机2发送线程结束],主机1不再接收[主机1接收线程结束];
socket结束
效果图
分别从两台主机的运行窗口处截图[两台主机时间上差个2秒,主机2快2秒。所以收发消息基本时间一致]
主机1 主机2
代码如下
import socket
import threading
import tkinter as tk
import time
import inspect
import ctypes
mywspn=('10.**.***.**',8800)
#######停止线程的模块,来源于网上
def _async_raise(tid, exctype):
"""raises the exception, performs cleanup if needed"""
tid = ctypes.c_long(tid)
if not inspect.isclass(exctype):
exctype = type(exctype)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
if res == 0:
raise ValueError("invalid thread id")
elif res != 1:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
raise SystemError("PyThreadState_SetAsyncExc failed")
def stop_thread(thread):
_async_raise(thread.ident, SystemExit)
########接收消息
def receive(s):
print('re start')
while True:
data,add=s.recvfrom(1024)
data=data.decode()
if data=='bye':
break
else:
print('from',add,'say:',data,'time is', time.asctime( time.localtime(time.time()) ))
stop_thread(t2)#停止接收消息的线程
if t1.isAlive():
print('t1 alive')
else:
print('socket closed')
s.close()
#######发送消息
def send(s):
print('send start')
# inp=input('发送:')
while True:
inp=mygui("Enter data")
print('I say:',inp,'time is', time.asctime( time.localtime(time.time()) ))
s.sendto(inp.encode(),mydell) #注意逻辑,先send再break
if inp=='bye':
s.sendto('I am offline'.encode(),mydell)
break
stop_thread(t1) #停止发送消息的线程
if t2.isAlive():
print('t2 alive')
else:
print('socket closed')
s.close()
#发送消息的GUI界面
def mygui(prompt=""):
root = tk.Tk()
tk.Label(root, text=prompt).pack()
entry = tk.Entry(root)
entry.pack()
result = None
def callback(event):
nonlocal result
result = entry.get()
root.destroy()
entry.bind("<Return>", callback)
root.mainloop()
return result
s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('',8888))
t1=threading.Thread(target=send,args=(s,))
t2=threading.Thread(target=receive,args=(s,))
t1.start()
t2.start()
网友评论