Tôi có một ổ cắm không chặn trong Python gọi là sock. Theo hiểu biết của tôi, phương thức recv() sẽ tăng một ngoại lệ nếu kết nối đã bị đóng bởi người ngang hàng, nhưng nó trả về một chuỗi trống ('') và tôi không biết tại sao.
Đây là tập lệnh tôi kiểm tra với (từ đây):
import sys import socket import fcntl, os import errno from time import sleep s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1',9999)) fcntl.fcntl(s, fcntl.F_SETFL, os.O_NONBLOCK) while True: try: msg = s.recv(4096) print("got data '{msg}'".format(msg=msg)) except socket.error, e: err = e.args[0] if err == errno.EAGAIN or err == errno.EWOULDBLOCK: sleep(1) print 'No data available' continue sys.exit(1)Nếu ngang hàng đóng kết nối, ổ cắm này được cho là tăng ____10 trên recv(), nhưng thay vào đó, nó chỉ trả về ''.
Tôi kiểm tra nó theo cách này, sử dụng hai thiết bị đầu cuối:
# Terminal 1 ~$ nc -l -p9999 # Terminal 2 ~$ python ./test_script.py # Terminal 1 typingsomestring # Terminal 2 No data available No data available No data available got data 'typingsomestring ' No data available No data available # Terminal 1 Ctrl+C # (killing nc) # Terminal 2 got data '' got data '' got data '' got data '' got data '' got data '' got data '' got data '' got data '' got data '' got data '' got data '' got data '' got data '' got data '' got data '' got data '' got data '' got data ''Đã hỏi ngày 2 tháng 1 năm 2021in Pythonby (50,2k điểm) Jan 2, 2021 in Python by (50.2k points)
Từ phân tích, tôi đã kết luận rằng trong ba trường hợp sau đây, ổ cắm.recv (recv_size) sẽ trở lại.
Sau khi kết nối được đóng lại. Ví dụ: phía máy khách được gọi là socket.close () hoặc bất kỳ lỗi ổ cắm nào xảy ra, nó sẽ trả về một chuỗi trống.
Một số thông tin đến, kích thước của dữ liệu nhiều hơn recv_size.
Đối với một số bản ghi, kích thước của dữ liệu ít hơn recv_size và không có thêm dữ liệu nào sau một thời gian ngắn (tôi thấy 0.1 sẽ hoạt động).
Thông tin chi tiết về #3:
#server.py
Trong khi đúng:
& nbsp; & nbsp; data = sock.recv (10)
& nbsp; & nbsp; In dữ liệu, 'EOF'
#client1.py
sock.sendall("12345")
Sock.Sendall ("A" * 50)
#client2.py
sock.sendall("12345")
time.sleep(0.1)
Sock.Sendall ("A" * 50)
#Khi tôi chạy client1.py, server.py echos:
12345AAAAA EOF
Aaaaaaaaaaa Eof
Aaaaaaaaaaa Eof
Aaaaaaaaaaa Eof
Aaaaaaaaaaa Eof
AAAAA EOF
#Khi tôi chạy client2.py, server.py echos:
12345 EOF
Aaaaaaaaaaa Eof
Aaaaaaaaaaa Eof
Aaaaaaaaaaa Eof
Aaaaaaaaaaa Eof
Aaaaaaaaaaa Eof
AAAAA EOF
#Khi tôi chạy client2.py, server.py echos: Answer
12345 EOF Jan 2, 2021 by vinita (108k points)
Kết luận của tôi có đúng không? & NBSP;
1 câu trả lời
Đã trả lời ngày 2 tháng 1 năm 2021by Vinita (108k điểm)
Vâng, phán đoán của bạn là chính xác. Ổ cắm.recv là một tín hiệu chặn.
Socket.Recv (1024) sẽ đọc ở mức tối đa 1024 byte, chặn nếu không có thông tin nào đang chờ được đọc. Nếu bạn không thu thập tất cả dữ liệu, một cuộc gọi khác đến socket.recv sẽ không chặn.
Làm thế nào để ngăn máy chủ ổ cắm Python gửi tin nhắn trống?
Tôi đã thiết lập một tập lệnh máy chủ/máy chủ ổ cắm cơ bản - hy vọng bằng cách nào đó thực hiện nó trong trang web và đã thấy rằng có thể thực hiện ứng dụng ứng dụng?
Dù sao, dường như không thể ngăn người dùng gặp sự cố máy chủ hoặc máy khách nếu họ nhập một tin nhắn trống (tức là nhấn trả về mà không cần nhập bất kỳ văn bản/dữ liệu nào). Có một cách dễ dàng để ngăn chặn điều này?
Madmartin | 362 Bài viết | Ngày 25 tháng 7 năm 2020, 7:16 sáng | permalink July 25, 2020, 7:16 a.m. | permalink
server.py
def server_program(): # get the hostname host = socket.gethostname() port = 8000 # initiate port no above 1024 server_socket = socket.socket() # get instance # look closely. The bind() function takes a tuple as argument server_socket.bind((host, port)) # bind host address and port together # configure how many clients the server can listen to simultaneously server_socket.listen(2) conn, address = server_socket.accept() # accept new connection print("Connection from: " + str(address) + " Now wait for message") while True: # receive data stream. it won't accept data packet greater than 1024 bytes data = conn.recv(1024).decode() #conn.sendall(data) if not data: # if data is not received break break print("from Client: " + str(data)) data = input('Enter message:-> ') conn.send(data.encode()) # send data to the client print('message sent!') conn.close() # close the connection if __name__ == '__main__': server_program()
Madmartin | 362 Bài viết | Ngày 25 tháng 7 năm 2020, 7:17 sáng | permalink July 25, 2020, 7:17 a.m. | permalink
Khách hàng PY:
Nhập ổ cắm
def client_program (): host = socket.gethostname () # vì cả hai mã đang chạy trên cùng một cổng PC = 8000 # số cổng máy chủ ổ cắm
client_socket = socket.socket() # instantiate client_socket.connect((host, port)) # connect to the server message = input(" Enter message:-> ") # take input while message.lower().strip() != 'bye': client_socket.send(message.encode()) # send message data = client_socket.recv(1024).decode() # receive response print('Received from SERVER: ' + data) # show in terminal message = input("Please send a message:-> ") # again take input client_socket.close() # close the connection
Nếu name == 'Main': client_program ()name == 'main': client_program()
Madmartin | 362 Bài viết | Ngày 25 tháng 7 năm 2020, 7:18 sáng | permalink July 25, 2020, 7:18 a.m. | permalink
Điều này hoạt động tốt (đã thêm: Nhập ổ cắm vào dòng trên cùng của máy chủ.py) - Nếu người dùng hoạt động chính xác nhưng nếu một người truy cập trả lại sai thời điểm hoặc thử gửi hai tin nhắn thì toàn bộ điều đó chỉ bị treo
Vì vậy, tôi muốn sửa nó và sau đó bằng cách nào đó thêm nó vào trang web/ứng dụng của tôi - điều đó có thể được thực hiện không?
Madmartin | 362 Bài viết | Ngày 25 tháng 7 năm 2020, 7:20 sáng | permalink July 25, 2020, 7:20 a.m. | permalink
Đừng chỉ gửi tin nhắn. Kiểm tra xem nó không trống và sau đó quyết định xem đó có phải là tin nhắn mà bạn muốn gửi hay nếu đó chỉ là một sự trở lại.
Tôi không sử dụng được tôi hiểu ý của bạn khi gửi 2 tin nhắn cùng một lúc. Tôi không thấy bất cứ điều gì trong mã cho phép gửi đồng thời 2 tin nhắn.
Tôi đã thử các phương pháp khác nhau cho điều đó, cho Ex tôi đã chèn:
if data == None conn.send(data.encode() if data = False while data != ' '
vv ... tất cả các loại kết hợp và không ai trong số họ thực hiện thủ thuật
tôi làm gì sai ở đây?
Madmartin | 362 Bài viết | Ngày 25 tháng 7 năm 2020, 10:35 sáng | permalink July 25, 2020, 10:35 a.m. | permalink
Đã thử điều này ngay bây giờ:
server.py
while True: data = input('Enter message:-> ') if data != ' ': conn.send(data.encode()) # send data to the client print('message sent!') else: print('cannot send blank message!') conn.close() # close the connection
Madmartin | 362 Bài viết | Ngày 25 tháng 7 năm 2020, 10:53 sáng | permalink July 25, 2020, 10:53 a.m. | permalink
client.py
if data == None: print('Recieved blank message!') # show in terminal else: print('Received from server: ' + data) # show in terminal message = input(" -> ") # again take input client_socket.close() # close the connection
Điều này không thực sự sắp xếp nó
Madmartin | 362 Bài viết | Ngày 25 tháng 7 năm 2020, 10:54 sáng | permalink July 25, 2020, 10:54 a.m. | permalink
Bạn có chắc rằng dữ liệu không có gì khi người dùng không nhập tin nhắn? Ngoài ra, bạn không thay đổi bất cứ điều gì - bạn vẫn đang chạy mã gửi tin nhắn khi dữ liệu không có (giả sử nó là bao giờ).
Nỗ lực đầu tiên của bạn có vẻ như nó có thể hoạt động nếu dữ liệu là một chuỗi trống khi người dùng chỉ truy cập trở lại.