簡體   English   中英

如何在Python中進行簡單的命令行聊天?

[英]How to make a simple command-line chat in 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 = raw_input('> ')
    if not data: break
    tcpCliSock.send(data)
    data = tcpCliSock.recv(BUFSIZE)
    if not data: break
    print data

tcpCliSock.close()

因此,如果另一個客戶端發送消息,該客戶端也將僅在發送消息后接收它。 我打賭你了解我。 我搜索了這個問題,發現了很多有趣的東西,比如異步I / O,線程,非阻塞同步,並發編程等等。 我也安裝了扭曲的包裝。 簡而言之,我一直在學習所有這些東西但卻找不到我想要的東西。 (當然,我會一直努力嘗試,直到我說到這一點。)

所以,我的問題是如何制作的? =)

你的問題不是很一致。 但是,您的程序根本不需要異步即可實現您的要求。

這是一個您最初想要的工作聊天腳本,只需要很少的更改。 它使用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是可行的(你可以在谷歌圖書搜索中閱讀包含這些內容的果殼中的大部分Python章節); 如果你想利用更多的抽象, asyncore是可用的,但Twisted更豐富,更強大。

聊天程序同時做兩件事。

  1. 觀看本地用戶的鍵盤並發送給遠程用戶(通過某種插座)

  2. 觀察遠程套接字並在本地控制台上顯示它們鍵入的內容。

你有幾種方法可以做到這一點。

  1. 一個程序,用於打開套接字和鍵盤,並使用選擇模塊查看哪個輸入就緒。

  2. 一個創建兩個線程的程序。 一個線程讀取遠程套接字並打印。 另一個線程讀取鍵盤並發送到遠程套接字。

  3. 一個分叉兩個子進程的程序。 一個子進程讀取遠程套接字並打印。 另一個子進程讀取鍵盤並發送到遠程套接字。

嗯,好吧,這就是我現在所擁有的。

服務器是這樣的:

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

現在是時候讓代碼看起來更好並添加一些功能。

伙計們,感謝您的幫助!

你應該使用select

校驗:

我在異步I / O中編寫了一個...它比完整的線程模型更容易包圍你。

如果你能掌握“談話”的源代碼,你可以學到很多東西。 看一個演示http://dsl.org/cookbook/cookbook_40.html#SEC559 ,或者如果你在Linux機器上試試吧...

它實時發送字符。

此外,ytalk是互動和多個用戶....有點像hudddlechat或篝火。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM