创建聊天(客户端)程序。如何添加同步对话?

2024-09-23 10:33:50 发布

您现在位置:Python中文网/ 问答频道 /正文

# -*- 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()

在Python3.5(Linux)中,当我发送“hi”时,此代码显示错误:

^{pr2}$

代码运行在python2.7上。在

我想让两个人同时说话,怎么办?目前,一次只能有一个人输入信息,我们必须等待其中一位参与者写下并点击才能继续,有人能帮我吗? 我使用netcat作为服务器。在


Tags: friendclientdemsgsocketdoudpprint
1条回答
网友
1楼 · 发布于 2024-09-23 10:33:50

下面是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)和{}。我们将从main函数调用startrecvdata(self),它将启动recvdata(self)线程。该函数将把接收到的任何数据打印到控制台。在

另外,请注意,在包装器的__init__函数中有settimeout(5),它在套接字连接上设置了5秒的超时。这样,我们可以干净地关闭整个程序,关闭并使用stop()函数关闭套接字。在

现在进入主循环。因为我们在包装器类中设置了所有函数,所以我们可以有一个超级简单和干净的循环:

^{pr2}$

在这个循环中,我们创建了一个socketwrapper的实例,它为我们初始化所有的东西。然后我们调用server.startrecvdata(),正如前面所说,它启动函数来接收和打印UDP连接中的数据。while not server.connected阻塞程序,直到线程启动。在

最后,我们有一个while server.connected循环,它在控制台中等待用户输入。我们检查用户是否想退出,如果他们想退出,我们设置server.connected = False和{}我们的while循环。
如果用户不想退出,我们将消息发送到UDP服务器。在

循环结束后,我们调用server.stop以确保套接字在退出应用程序之前是关闭的。在

相关问题 更多 >