[英]How to accept two connections using sockets in Python
我正在做一個聊天程序。 但是目前只能有一個客戶。 我要如何使其能夠接受兩個客戶? 在套接字方面,我還是有點菜鳥的,所以您可以很詳盡地解釋一下嗎?
服務器代碼:
import socket
def mainFunc():
host = ""
port = 50000
ipList = []
nickNameList = []
num = True
s = socket.socket()
s.bind((host, port))
s.listen(1)
c, addr = s.accept()
print("Connection from: " + str(addr) + "\n")
ipList.insert(0, str(addr))
while True:
data = c.recv(1024)
if not data:
break
if num == True:
nickNameList.insert(0, str(data))
num = False
else:
print("From " + nickNameList[0] + ": " + str(data) + "\n")
message = raw_input("Message you want to send: ")
print("\n")
c.send(message)
c.close()
我嘗試將s.listen(1)更改為s.listen(2)。 但這似乎不允許第二個人進行聯系。 有人可以解釋為什么嗎?
一個accept
呼叫將accept
一個連接。 要接受兩種連接方式,呼叫accept
兩次。
如果要順序連接兩個,但一次不超過一個, c, addr = s.accept()
需要圍繞c, addr = s.accept()
的循環c, addr = s.accept()
及其c, addr = s.accept()
所有內容。 然后它將接受一個連接,處理該連接,直到套接字關閉並執行break
,然后處理第二個連接,依此類推。
在這種情況下, listen
積壓(即s.listen(2)
在處理第一個連接時,它不會排隊等待2個以上的等待連接。 之后的任何人都會被拒絕。
如果要同時進行兩個連接,則必須執行以下兩項操作之一:
gevent
是相同的想法。) asyncio
到圍繞select
簡單循環)。) 在這種情況下,僅當您的程序太慢而無法跟上進入連接的速度時, listen
積壓才真正重要。在這種情況下,拒絕新連接通常比接受新連接並進一步放慢速度要好,因此保持少量積壓是一個好主意。
但是由於您的連接處理程序會在每個套接字消息之后阻塞raw_input
,至少可以這樣說,這將是一個怪異的設計。 (不是阻塞部分,您可以通過為stdin分配線程, select
條目,協程等來解決此問題。但是輸入實際上會發生什么。您只有8個連接,只有1個輸入。哪個連接可以得到結果用戶何時輸入內容?)
這是一個簡單的線程服務器:
def connection(c, addr):
while True:
# your existing while True loop
while True:
c, addr = s.accept()
t = threading.Thread(target=connection, args=(c, addr))
t.start()
但是,對於您希望能夠以某種方式關閉的現實服務器,您將需要提供某種方式來關閉連接線程。 同樣,對於在客戶端之間進行交互的服務器(例如向一個用戶發送聊天消息給所有其他用戶),您需要某種方式在線程之間傳遞消息或在線程之間共享信息。 通常,每個連接最終需要兩個線程-一個線程在c.recv
上c.recv
,另一個線程在隊列上c.recv
,並與其他用戶的消息一起調用c.send
。
對於多路復用服務器,不同的方法看起來非常不同,但是所有方法都有很好的示例。 見asyncio
, selectors
了他們的榜樣, Socket編程HOWTO的select
的例子,而谷歌對於像扭曲,GEVENT等第三方庫的例子
附帶說明一下,您似乎希望send
肯定能一次發送完整的消息,而另一端的recv
將接收到整個消息,而不會收到其他任何消息。 TCP不能保證沒有這種事情。 有關更多詳細信息,請參見套接字是字節流,而不是消息流 。
另外,在nickNameList.insert(0, str(data))
, str
是什么? 在Python 2.x中, data
已經是一個str
,因此這沒有充分的理由浪費了額外的副本。 在Python 3.x中, data
是一個bytes
,因此這會將其轉換為字符串表示形式,例如"b'0Cool'"
而不是"0Cool"
,這幾乎肯定不是您想要的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.