# -*- coding: utf-8 -*-
#!/usr/bin/python3
import socket
# nao tem servidor UDP no google -> vamos usar netcat como servidor UDP!
#Programa de chat: so fala um de cada vez
#implementar falando ao mesmo tempo
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
"""
pacotes_recebidos = client.recvfrom(1024) devolve uma tupla:
(' llallalaaaa\n', ('192.168.1.4', 667))
msg recebida + (IP,porta)
"""
try:
while 1: #while True
client.sendto(input("Voce: ") +"\n", ("192.168.1.4", 668)) # endereço do servidor UDP do kali linux usando netcat
msg, friend = client.recvfrom(1024)
print(str(friend) + ": " + msg)
#se quiser apenas o ip: use friend[0]
# convertemos str(friend) porque recebemos o erro:
# (TypeError(can only concatenate tuple (not str) to tuple,))
client.close()
except Exception as erro:
print("Conexao falhou ")
print("O erro foi: ", erro)
client.close()
在python 3.5(Linux)中,当我发送“ hi”时,此代码显示错误:
('O erro foi: ', NameError("name 'hi' is not defined",))
该代码在python 2.7上运行。
我想让两个人可以同时讲话,怎么办?目前,一次只能输入一个人的信息,我们必须等待其中一位参与者写信并点击继续才能有人可以帮助我吗?我使用netcat作为服务器。
这是python3中“多线程” UDP python客户端的示例,该客户端允许同时发送和接收消息。
我个人喜欢为socket
具有所有内置线程和函数的类创建一个包装器,因此我们将从包装器开始。
import socket
import threading
class socketwrapper:
def __init__(self, host, port):
self.server = (host, port)
self.client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.client.settimeout(5) # Time is in seconds
self.connected = False
def startrecvdata(self):
recvThread = threading.Thread(target=self.recvdata)
recvThread.daemon = True
recvThread.start()
self.connected = True
def recvdata(self):
while self.connected:
try:
data, friend = self.client.recvfrom(1024)
if data:
print(str(friend) + ": " + data.decode('utf-8'))
except socket.timeout:
else:
print("No Message Received before timeout.")
continue
except:
self.connected = False
self.stop()
def sendmessage(self, data):
data += "\n"
self.client.sendto(data.encode('utf-8'), self.server)
def stop(self):
self.client.shutdown(socket.SHUT_RDWR)
self.client.close()
如您所见,我们在其中有两个函数,您应该注意的两个是startrecvdata(self)
和recvdata(self)
。我们将从startrecvdata(self)
主函数调用,这将启动recvdata(self)
线程。该功能会将所有接收到的数据打印到控制台。
另外,请注意,我们具有包装器settimeout(5)
的__init__
功能,该功能在套接字连接上设置5秒超时。这样,我们可以干净地关闭整个程序,使用该stop()
函数关闭和关闭套接字。
现在进入主循环。由于我们在wrapper类中设置了所有函数,因此我们可以拥有一个超级简单和干净的循环:
def main():
server = socketwrapper('192.168.1.1', 30000)
server.startrecvdata()
while not server.connected:
continue
print("Connected to server! Type 'exit' to quit.")
while server.connected:
message = input("Voce: ")
if message == "exit":
server.connected = False
break
server.sendmessage(message)
server.stop()
在此循环中,我们创建了我们的实例,该实例为我们socketwrapper
初始化了所有内容。然后我们调用server.startrecvdata()
它,如上所述,启动函数以从UDP连接接收和打印数据。该while not server.connected
块的程序,直到线程已经开始。
最后,我们有一个while server.connected
循环,它等待控制台中的用户输入。我们检查用户是否要退出,如果要退出,则设置server.connected = False
和break
while循环。
如果用户不想退出,我们会将消息发送到UDP服务器。
循环结束后,我们调用server.stop
以确保在退出应用程序之前关闭套接字。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句