3 回答

TA貢獻(xiàn)1826條經(jīng)驗(yàn) 獲得超6個(gè)贊
您需要為發(fā)送和接收創(chuàng)建兩個(gè)單獨(dú)的線程。您編寫循環(huán)的方式不適用于同時(shí)進(jìn)行雙向通信。因?yàn)樵诎l(fā)送消息后,循環(huán)正在等待接收某些東西。[如果您想通過互聯(lián)網(wǎng)運(yùn)行代碼,請(qǐng)?zhí)鎿Qlocalhost為所需的 IP 地址行HOST = 'localhost'] 讓我分享一個(gè)解決方案(這是我在 TAing 本科網(wǎng)絡(luò)課程時(shí)完成的示例解決方案):
我已經(jīng)在 Linux 機(jī)器(Ubuntu 18.04)上測(cè)試了代碼。我有學(xué)生在他們的 Mac 上成功運(yùn)行了這個(gè)。我不確定它是否在 Windows 機(jī)器上運(yùn)行。即使它在 Windows 機(jī)器上不起作用,一些小的修改也應(yīng)該可以解決問題。
服務(wù)端代碼(你需要先運(yùn)行這個(gè)): chatServerDuplex.py
# Import socket module
from socket import *
import threading
import sys # In order to terminate the program
FLAG = False # this is a flag variable for checking quit
# function for receiving message from client
def recv_from_client(conn):
global FLAG
try:
# Receives the request message from the client
while True:
if FLAG == True:
break
message = conn.recv(1024).decode()
# if 'q' is received from the client the server quits
if message == 'q':
conn.send('q'.encode())
print('Closing connection')
conn.close()
FLAG = True
break
print('Client: ' + message)
except:
conn.close()
# function for receiving message from client
def send_to_client(conn):
global FLAG
try:
while True:
if FLAG == True:
break
send_msg = input('')
# the server can provide 'q' as an input if it wish to quit
if send_msg == 'q':
conn.send('q'.encode())
print('Closing connection')
conn.close()
FLAG = True
break
conn.send(send_msg.encode())
except:
conn.close()
# this is main function
def main():
threads = []
global FLAG
# TODO (1) - define HOST name, this would be an IP address or 'localhost' (1 line)
HOST = 'localhost'
# TODO (2) - define PORT number (1 line) (Google, what should be a valid port number)
# make sure the ports are not used for any other application
serverPort = 6789
# Create a TCP server socket
#(AF_INET is used for IPv4 protocols)
#(SOCK_STREAM is used for TCP)
# TODO (3) - CREATE a socket for IPv4 TCP connection (1 line)
serverSocket = socket(AF_INET, SOCK_STREAM)
# Bind the socket to server address and server port
# TODO (4) - bind the socket for HOSR and serverPort (1 line)
serverSocket.bind((HOST, serverPort))
# Listen to at most 1 connection at a time
# TODO (5) - listen and wait for request from client (1 line)
serverSocket.listen(1)
# Server should be up and running and listening to the incoming connections
print('The chat server is ready to connect to a chat client')
# TODO (6) - accept any connection request from a client (1 line)
connectionSocket, addr = serverSocket.accept()
print('Sever is connected with a chat client\n')
t_rcv = threading.Thread(target=recv_from_client, args=(connectionSocket,))
t_send = threading.Thread(target=send_to_client, args=(connectionSocket,))
# call the function to receive message server
#recv_from_server(clientSocket)
threads.append(t_rcv)
threads.append(t_send)
t_rcv.start()
t_send.start()
t_rcv.join()
t_send.join()
# closing serverScoket before exiting
print('EXITING')
serverSocket.close()
#Terminate the program after sending the corresponding data
sys.exit()
# This is where the program starts
if __name__ == '__main__':
main()
客戶端代碼: chatClientDuplex.py
from socket import *
import threading
import sys
FLAG = False # this is a flag variable for checking quit
# function for receiving message from client
def send_to_server(clsock):
global FLAG
while True:
if FLAG == True:
break
send_msg = input('')
clsock.sendall(send_msg.encode())
# function for receiving message from server
def recv_from_server(clsock):
global FLAG
while True:
data = clsock.recv(1024).decode()
if data == 'q':
print('Closing connection')
FLAG = True
break
print('Server: ' + data)
# this is main function
def main():
threads = []
# TODO (1) - define HOST name, this would be an IP address or 'localhost' (1 line)
HOST = 'localhost' # The server's hostname or IP address
# TODO (2) - define PORT number (1 line) (Google, what should be a valid port number)
PORT = 6789 # The port used by the server
# Create a TCP client socket
#(AF_INET is used for IPv4 protocols)
#(SOCK_STREAM is used for TCP)
# TODO (3) - CREATE a socket for IPv4 TCP connection (1 line)
clientSocket = socket(AF_INET, SOCK_STREAM)
# request to connect sent to server defined by HOST and PORT
# TODO (4) - request a connection to the server (1 line)
clientSocket.connect((HOST, PORT))
print('Client is connected to a chat sever!\n')
# call the function to send message to server
#send_to_server(clientSocket)
t_send = threading.Thread(target=send_to_server, args=(clientSocket,))
# call the function to receive message server
#recv_from_server(clientSocket)
t_rcv = threading.Thread(target=recv_from_server, args=(clientSocket,))
threads.append(t_send)
threads.append(t_rcv)
t_send.start()
t_rcv.start()
t_send.join()
t_rcv.join()
print('EXITING')
sys.exit()
# This is where the program starts
if __name__ == '__main__':
main()

TA貢獻(xiàn)1995條經(jīng)驗(yàn) 獲得超2個(gè)贊
System123456 問題是當(dāng)服務(wù)器偵聽并且客戶端連接到它時(shí),您構(gòu)建了一個(gè)客戶端 - 服務(wù)器系統(tǒng)。嘗試查看點(diǎn)對(duì)點(diǎn)系統(tǒng),而不是每個(gè)節(jié)點(diǎn)都是平等的。為了構(gòu)建聊天室,您可能會(huì)查看 DHT 節(jié)點(diǎn)。

TA貢獻(xiàn)1853條經(jīng)驗(yàn) 獲得超9個(gè)贊
您的第一個(gè)問題可能是由于默認(rèn)情況下 python 套接字是阻塞的。這意味著,例如,在 line 上message = s.recv(1024)
,您的程序?qū)⒗^續(xù)偵聽,并且在收到某些內(nèi)容之前不會(huì)繼續(xù)執(zhí)行腳本的其余部分。
如果您希望兩個(gè)人能夠同時(shí)接收和發(fā)送,您可能需要研究非阻塞套接字和一些異步編程。官方文檔中的此操作方法可能對(duì)您有所幫助:https : //docs.python.org/2/howto/sockets.html#non-blocking-sockets
添加回答
舉報(bào)