Hướng dẫn python socket recv empty string - python socket recv chuỗi trống

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.

Hướng dẫn python socket recv empty string - python socket recv chuỗi trống
Glenn | 8448 Bài viết | Nhân viên Pythonany ở đâu | Ngày 25 tháng 7 năm 2020, 9:24 sáng | permalink July 25, 2020, 9:24 a.m. | permalink

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.

Hướng dẫn python socket recv empty string - python socket recv chuỗi trống
Glenn | 8448 Bài viết | Nhân viên Pythonany ở đâu | Ngày 25 tháng 7 năm 2020, 11 giờ sáng | permalink July 25, 2020, 11 a.m. | permalink

Ổ cắm recv trả lại Python là gì?

Cuộc gọi recv () chỉ áp dụng cho các ổ cắm được kết nối. Cuộc gọi này trả về độ dài của tin nhắn hoặc dữ liệu đến. Nếu một gói datagram quá dài để phù hợp với bộ đệm được cung cấp, các ổ cắm Datagram sẽ loại bỏ các byte dư thừa.the length of the incoming message or data. If a datagram packet is too long to fit in the supplied buffer, datagram sockets discard excess bytes.

SOCKED có phải chờ dữ liệu không?

Nếu không có dữ liệu đến có sẵn tại ổ cắm, các khối cuộc gọi RECV và chờ dữ liệu đến theo các quy tắc chặn được xác định cho WSARECV với cờ MSG_PARTIAL không được đặt trừ khi ổ cắm không chặn.Trong trường hợp này, giá trị của socket_error được trả về với mã lỗi được đặt thành wsaewouldblock.

Có phải socket nghe chặn python?

Tất cả các phương pháp ổ cắm đang chặn.Ví dụ: khi nó đọc từ ổ cắm hoặc ghi vào nó, chương trình không thể làm gì khác.Một giải pháp khả thi là ủy thác làm việc với khách hàng để tách các chủ đề.. For example, when it reads from a socket or writes to it the program can't do anything else. One possible solution is to delegate working with clients to separate threads.

Không phải là gì

Khi bạn thực hiện một ổ cắm không chặn bằng cách gọi SetBlocking (0), nó sẽ không bao giờ chờ đợi hoạt động hoàn tất.Vì vậy, khi bạn gọi phương thức gửi (), nó sẽ đặt càng nhiều dữ liệu trong bộ đệm càng tốt và trả về.Vì điều này được đọc bởi kết nối từ xa, dữ liệu được xóa khỏi bộ đệm.it will never wait for the operation to complete. So when you call the send() method, it will put as much data in the buffer as possible and return. As this is read by the remote connection, the data is removed from the buffer.