Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何用Python进行简单的命令行聊天?_Python - Fatal编程技术网

如何用Python进行简单的命令行聊天?

如何用Python进行简单的命令行聊天?,python,Python,我学习网络编程,想用Python编写一个简单的命令行聊天 我想知道如何使接收和输入保持恒定,以便随时发送 如您所见,此客户端一次只能执行一项作业: from socket import * HOST = 'localhost' PORT = 21567 BUFSIZE = 1024 ADDR = (HOST, PORT) tcpCliSock = socket(AF_INET, SOCK_STREAM) tcpCliSock.connect(ADDR) while 1: data

我学习网络编程,想用Python编写一个简单的命令行聊天

我想知道如何使接收和输入保持恒定,以便随时发送

如您所见,此客户端一次只能执行一项作业:

from socket import *

HOST = 'localhost'
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST, PORT)

tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)

while 1:
    data = raw_input('> ')
    if not data: break
    tcpCliSock.send(data)
    data = tcpCliSock.recv(BUFSIZE)
    if not data: break
    print data

tcpCliSock.close()
因此,如果另一个客户机发送消息,该客户机也只会在发送消息后接收消息。我打赌你一定理解我。我在谷歌上搜索过这件事,发现了很多有趣的东西,比如异步I/O、线程、非阻塞同步、并发编程等等。我还安装了twisted软件包。简言之,我一直在学习这些东西,但还没有找到我想要的。(当然,我会一直努力,直到我说到点子上。)


那么,我的问题是如何做到这一点

如果你想从头开始编写代码
select
是一个不错的选择(你可以在谷歌图书搜索上阅读Python的大部分章节,简而言之,其中涵盖了这些内容);如果您想利用更多的抽象,
asyncore
是可用的,但更丰富、更强大。

您应该使用

检查:


    • 我用异步I/O写了一个。。。这比全线程模型更容易理解

      如果你能掌握“talk”的源代码,你就能学到很多。看一个演示,如果你在linux机器上,也可以自己试一试

      它实时发送字符


      此外,ytalk是交互式的多用户。。。。有点像Huddlechat或campfire。

      聊天程序同时做两件事

    • 监视本地用户的键盘并发送给远程用户(通过某种插座)

    • 监视远程套接字并显示它们在本地控制台上键入的内容

    • 你有几种方法可以做到这一点

    • 打开插座和键盘并使用模块查看哪个模块已准备好输入的程序

    • 创建两个线程的程序。一个线程读取远程套接字并打印。另一个线程读取键盘并发送到远程套接字

    • 分叉两个子进程的程序。一个子进程读取远程套接字并打印。另一个子进程读取键盘并发送到远程套接字


    • 好吧,好吧,这就是我此刻的感受

      服务器如下所示:

      import asyncore
      import socket
      
      clients = {}
      
      class MainServerSocket(asyncore.dispatcher):
          def __init__(self, port):
              asyncore.dispatcher.__init__(self)
              self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
              self.bind(('',port))
              self.listen(5)
          def handle_accept(self):
              newSocket, address = self.accept( )
              clients[address] = newSocket
              print "Connected from", address
              SecondaryServerSocket(newSocket)
      
      class SecondaryServerSocket(asyncore.dispatcher_with_send):
          def handle_read(self):
              receivedData = self.recv(8192)
              if receivedData:
                  every = clients.values()
                  for one in every:
                      one.send(receivedData+'\n')
              else: self.close( )
          def handle_close(self):
              print "Disconnected from", self.getpeername( )
              one = self.getpeername( )
              del clients[one]
      
      MainServerSocket(21567)
      asyncore.loop( )
      
      from Tkinter import *
      from socket import *
      import thread
      
      HOST = 'localhost'
      PORT = 21567
      BUFSIZE = 1024
      ADDR = (HOST, PORT)
      
      tcpCliSock = socket(AF_INET, SOCK_STREAM)
      tcpCliSock.connect(ADDR)
      
      class Application(Frame):
          def __init__(self, master):
              Frame.__init__(self, master)
              self.grid()
              self.create_widgets()
              self.socket()
      
          def callback(self, event):
              message = self.entry_field.get()
              tcpCliSock.send(message)
      
          def create_widgets(self):
              self.messaging_field = Text(self, width = 110, height = 20, wrap = WORD)
              self.messaging_field.grid(row = 0, column = 0, columnspan = 2, sticky = W)
      
              self.entry_field = Entry(self, width = 92)
              self.entry_field.grid(row = 1, column = 0, sticky = W)
              self.entry_field.bind('<Return>', self.callback)
      
          def add(self, data):
              self.messaging_field.insert(END, data)
      
          def socket(self):
              def loop0():
                  while 1:
                      data = tcpCliSock.recv(BUFSIZE)
                      if data: self.add(data)
      
              thread.start_new_thread(loop0, ())
      
      
      
      root = Tk()
      root.title("Chat client")
      root.geometry("550x260")
      
      app = Application(root)
      
      root.mainloop()
      
      客户机是这样的:

      import asyncore
      import socket
      
      clients = {}
      
      class MainServerSocket(asyncore.dispatcher):
          def __init__(self, port):
              asyncore.dispatcher.__init__(self)
              self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
              self.bind(('',port))
              self.listen(5)
          def handle_accept(self):
              newSocket, address = self.accept( )
              clients[address] = newSocket
              print "Connected from", address
              SecondaryServerSocket(newSocket)
      
      class SecondaryServerSocket(asyncore.dispatcher_with_send):
          def handle_read(self):
              receivedData = self.recv(8192)
              if receivedData:
                  every = clients.values()
                  for one in every:
                      one.send(receivedData+'\n')
              else: self.close( )
          def handle_close(self):
              print "Disconnected from", self.getpeername( )
              one = self.getpeername( )
              del clients[one]
      
      MainServerSocket(21567)
      asyncore.loop( )
      
      from Tkinter import *
      from socket import *
      import thread
      
      HOST = 'localhost'
      PORT = 21567
      BUFSIZE = 1024
      ADDR = (HOST, PORT)
      
      tcpCliSock = socket(AF_INET, SOCK_STREAM)
      tcpCliSock.connect(ADDR)
      
      class Application(Frame):
          def __init__(self, master):
              Frame.__init__(self, master)
              self.grid()
              self.create_widgets()
              self.socket()
      
          def callback(self, event):
              message = self.entry_field.get()
              tcpCliSock.send(message)
      
          def create_widgets(self):
              self.messaging_field = Text(self, width = 110, height = 20, wrap = WORD)
              self.messaging_field.grid(row = 0, column = 0, columnspan = 2, sticky = W)
      
              self.entry_field = Entry(self, width = 92)
              self.entry_field.grid(row = 1, column = 0, sticky = W)
              self.entry_field.bind('<Return>', self.callback)
      
          def add(self, data):
              self.messaging_field.insert(END, data)
      
          def socket(self):
              def loop0():
                  while 1:
                      data = tcpCliSock.recv(BUFSIZE)
                      if data: self.add(data)
      
              thread.start_new_thread(loop0, ())
      
      
      
      root = Tk()
      root.title("Chat client")
      root.geometry("550x260")
      
      app = Application(root)
      
      root.mainloop()
      
      从Tkinter导入*
      从套接字导入*
      导入线程
      主机='localhost'
      端口=21567
      BUFSIZE=1024
      地址=(主机,端口)
      tcpCliSock=套接字(AF_INET,SOCK_STREAM)
      tcpCliSock.connect(地址)
      课程申请(框架):
      定义初始(自我,主):
      帧。\uuuu初始化(自,主)
      self.grid()
      self.create_widgets()
      self.socket()
      def回调(自身、事件):
      message=self.entry\u field.get()
      tcpCliSock.send(消息)
      def创建_小部件(自):
      self.messaging_字段=文本(self,宽度=110,高度=20,换行=WORD)
      self.messaging_field.grid(行=0,列=0,列span=2,粘性=W)
      self.entry\u字段=输入(self,宽度=92)
      self.entry_field.grid(行=1,列=0,粘性=W)
      self.entry\u field.bind(“”,self.callback)
      def添加(自身、数据):
      self.messaging_field.insert(结束,数据)
      def插座(自):
      def loop0():
      而1:
      数据=tcpCliSock.recv(BUFSIZE)
      如果数据:self.add(数据)
      线程。启动新线程(loop0,())
      root=Tk()
      root.title(“聊天客户端”)
      根几何(“550x260”)
      app=应用程序(根)
      root.mainloop()
      
      现在是时候让代码看起来更好并添加一些功能了


      谢谢你们的帮助,伙计们

      你的问题不太连贯。但是,您的程序根本不需要是异步的,就可以达到您的要求

      这是一个可以正常工作的聊天脚本,您最初只需要进行很少的更改。它使用1个线程进行接收,1个线程进行发送,两者都使用阻塞套接字。它比使用异步方法简单得多

      from socket import *
      from threading import Thread
      import sys
      
      HOST = 'localhost'
      PORT = 21567
      BUFSIZE = 1024
      ADDR = (HOST, PORT)
      
      tcpCliSock = socket(AF_INET, SOCK_STREAM)
      tcpCliSock.connect(ADDR)
      
      def recv():
          while True:
              data = tcpCliSock.recv(BUFSIZE)
              if not data: sys.exit(0)
              print data
      
      Thread(target=recv).start()
      while True:
          data = raw_input('> ')
          if not data: break
          tcpCliSock.send(data)
      
      tcpCliSock.close()
      

      是我读过的最糟糕的文档。没有例子!我没有从那个来源得到任何消息…好吧,然后在其他地方阅读关于select API的内容。谷歌确实有用。哦,我说的是一个命令行聊天,但最终得到了一个GUI应用。尽管如此,这并不会使事情有太大的不同。>这比使用异步方法简单得多。嘿,老兄,我在聊天客户端的什么地方使用异步方法?(好吧,我不关心服务器;我对客户端很感兴趣。)我的聊天客户端和你的一样,只是你导入线程模块,我导入线程模块。不过,谢谢你!区别在于您导入了asyncore,因此使用了异步方法。此外,您还包括了一个完全不必要的GUI,但除此之外,它是相同的。asyncore模块是在服务器应用程序中导入的,而不是在客户端应用程序中导入的。顺便说一下,GUI是必要的。试试你写的代码。启动两个客户端并尝试通信。那样不美。但这是另一个故事