Socket.send python

Chào mừng đến với phần 3 của hướng dẫn socket với Python. Chúng ta đã học cách gửi và nhận dữ liệu chuỗi qua socket, và bây giờ tôi muốn nói về dưa chua. Không phải thức ăn, mà là kỹ thuật tuần tự hóa trong Python

Trong Python, mọi thứ đều là một đối tượng và tất cả các đối tượng của bạn có thể được sắp xếp theo thứ tự với Pickle. Tuần tự hóa là chuyển đổi đối tượng của bạn thành byte

và chúng tôi gửi byte với ổ cắm. Điều này có nghĩa là bạn có thể giao tiếp giữa các chương trình python của mình cục bộ hoặc từ xa, thông qua ổ cắm, sử dụng dưa chua. Vì vậy, bây giờ, theo nghĩa đen bất cứ điều gì. chức năng, một từ điển khổng lồ, một số mảng, mô hình TensorFlow. vv có thể được gửi qua lại giữa các chương trình của bạn. Hãy xem một ví dụ nhanh về điều đó trước khi tôi kết thúc hướng dẫn này

Vì vậy, trước tiên, nhanh lên, trong trường hợp bạn không biết về dưa chua, hãy chuyển đổi dưa chua thành chuỗi byte

>>> import pickle
>>> d = {1:"hi", 2: "there"}
>>> msg = pickle.dumps(d)
>>> msg
b'\x80\x03}q\x00(K\x01X\x02\x00\x00\x00hiq\x01K\x02X\x05\x00\x00\x00thereq\x02u.'

Bây giờ, đó là tin nhắn của chúng ta, chúng ta chỉ cần gửi nó. Khi chúng tôi nhận được nó, chúng tôi có thể đọc nó với

>>> recd = pickle.loads(msg)
>>> recd
{1: 'hi', 2: 'there'}
0

>>> recd = pickle.loads(msg)
>>> recd
{1: 'hi', 2: 'there'}

Được rồi, chúng ta hãy đặt nó lại với nhau và gửi nó.

>>> recd = pickle.loads(msg)
>>> recd
{1: 'hi', 2: 'there'}
1 của chúng tôi sẽ có mã sau để gửi tin nhắn

    d = {1:"hi", 2: "there"}
    msg = pickle.dumps(d)
    msg = bytes(f"{len(msg):<{HEADERSIZE}}", 'utf-8')+msg
    print(msg)
    clientsocket.send(msg)

Tạo tập lệnh đầy đủ (đã loại bỏ rất nhiều từ trước đó vì chúng tôi chỉ đang cố gắng minh họa các đối tượng gửi)

>>> recd = pickle.loads(msg)
>>> recd
{1: 'hi', 2: 'there'}
1
import socket
import time
import pickle


HEADERSIZE = 10

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1243))
s.listen(5)

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")

    d = {1:"hi", 2: "there"}
    msg = pickle.dumps(d)
    msg = bytes(f"{len(msg):<{HEADERSIZE}}", 'utf-8')+msg
    print(msg)
    clientsocket.send(msg)

Trong trường hợp trên cũng vậy, chúng tôi đang gửi một tiêu đề được tính bằng byte, thay vì ký tự, điều này thực sự có ý nghĩa hơn trong cả hai trường hợp. Bây giờ, khách hàng của chúng tôi cần xử lý việc này. Để phù hợp với thay đổi này, chúng tôi thay đổi thông báo bắt đầu của mình thành (cả ban đầu, sau đó sau khi thông báo hoàn tất)

Chào mừng bạn đến với hướng dẫn về ổ cắm với Python 3. Chúng tôi có rất nhiều thứ để trang trải, vì vậy hãy bắt đầu ngay. Thư viện

s.listen(5)
4 là một phần của thư viện tiêu chuẩn, vì vậy bạn đã có nó

________số 8_______

Biến

s.listen(5)
5 là ổ cắm TCP/IP của chúng tôi. AF_INET liên quan đến họ hoặc miền, nó có nghĩa là ipv4, trái ngược với ipv6 với AF_INET6. SOCK_STREAM có nghĩa là nó sẽ là một ổ cắm TCP, đây là loại ổ cắm của chúng tôi. TCP có nghĩa là nó sẽ được định hướng kết nối, trái ngược với không kết nối

Được rồi, vậy ổ cắm là gì?

Một ổ cắm sẽ được gắn với một số cổng trên một số máy chủ. Nói chung, bạn sẽ có loại thực thể hoặc chương trình máy khách hoặc máy chủ

Trong trường hợp của

s.listen(5)
6, bạn sẽ liên kết một ổ cắm với một số cổng trên máy chủ (localhost). Trong trường hợp của
s.listen(5)
7, bạn sẽ kết nối một ổ cắm với máy chủ đó, trên cùng một cổng mà mã phía máy chủ đang sử dụng

Hãy tạo mã này cho đến nay phía máy chủ của chúng tôi

s.bind((socket.gethostname(), 1234))

Đối với ổ cắm IP, địa chỉ mà chúng tôi liên kết là một bộ tên máy chủ và số cổng

Bây giờ chúng ta đã hoàn thành việc đó, hãy lắng nghe các kết nối đến. Chúng tôi chỉ có thể xử lý một kết nối tại một thời điểm nhất định, vì vậy chúng tôi muốn cho phép một số loại hàng đợi, chỉ trong trường hợp chúng tôi gặp sự cố nhẹ. Nếu ai đó cố gắng kết nối khi hàng đợi đã đầy, họ sẽ bị từ chối

Hãy xếp hàng 5 người

s.listen(5)

Và bây giờ, chúng ta chỉ lắng nghe

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")

Mã đầy đủ cho

s.listen(5)
8

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1234))
s.listen(5)

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")

Bây giờ chúng ta cần tạo mã của khách hàng

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Bây giờ, vì đây là khách hàng, chứ không phải là

s.listen(5)
9, chúng tôi sẽ chuyển sang
while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
0

s.connect((socket.gethostname(), 1234))

Theo nghĩa truyền thống hơn về máy khách và máy chủ, bạn sẽ không thực sự có máy khách và máy chủ trên cùng một máy. Nếu bạn muốn có hai chương trình nói chuyện với nhau cục bộ, bạn có thể làm điều này, nhưng thông thường, máy khách của bạn sẽ có nhiều khả năng kết nối với một số máy chủ bên ngoài, sử dụng địa chỉ IP công cộng của nó, không phải

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
1. Thay vào đó, bạn sẽ chuyển chuỗi IP

Full

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 mã tính đến thời điểm này

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1234))

Được rồi, bây giờ chúng tôi chỉ chạy cả hai. Đầu tiên, hãy chạy máy chủ của chúng tôi

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
3

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
4

Trên máy chủ của chúng tôi, chúng ta sẽ thấy

Connection from ('192.168.86.34', 54276) has been established.

Tuy nhiên, khách hàng của chúng tôi chỉ thoát sau đó vì nó đã hoàn thành công việc của mình

Vì vậy, chúng tôi đã tạo kết nối và điều đó thật tuyệt, nhưng chúng tôi thực sự muốn gửi tin nhắn và/hoặc dữ liệu qua lại. làm sao chúng ta làm việc đó bây giờ?

Ổ cắm của chúng tôi có thể dữ liệu

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
5 và
while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
6. Những phương pháp xử lý dữ liệu xử lý trong bộ đệm. Bộ đệm xảy ra trong khối dữ liệu có kích thước cố định. Hãy xem điều đó trong hành động

Bên trong

s.listen(5)
8, hãy thêm

    clientsocket.send(bytes("Hey there!!!","utf-8"))

Vào vòng lặp

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
8 của chúng tôi, vì vậy mã đầy đủ của chúng tôi cho
s.listen(5)
8 trở thành

s.bind((socket.gethostname(), 1234))
0

Vì vậy, chúng tôi đã gửi một số dữ liệu, bây giờ chúng tôi muốn nhận nó. Vì vậy, trong

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 của chúng tôi, chúng tôi sẽ làm

s.bind((socket.gethostname(), 1234))
1

Điều này có nghĩa là ổ cắm của chúng tôi sẽ cố gắng nhận dữ liệu, với kích thước bộ đệm là 1024 byte mỗi lần

Sau đó, hãy làm điều gì đó cơ bản với dữ liệu chúng tôi nhận được, chẳng hạn như in nó ra

s.bind((socket.gethostname(), 1234))
2

Thật tuyệt, mã

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 đầy đủ của chúng tôi hiện đã có

s.bind((socket.gethostname(), 1234))
3

Bây giờ, hãy chạy cả

s.listen(5)
8 và sau đó là
while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2. Chương trình
s.listen(5)
8 của chúng tôi

s.bind((socket.gethostname(), 1234))
4

Trong khi

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 của chúng tôi hiện đang hiển thị

s.bind((socket.gethostname(), 1234))
5

Và nó thoát. Được rồi, vậy hãy điều chỉnh bộ đệm đó một chút, thay đổi

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2
while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
6 thành 8 byte mỗi lần

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2

s.bind((socket.gethostname(), 1234))
6

Bây giờ, chạy lại

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2, và thay vào đó, bạn sẽ thấy một cái gì đó giống như

s.bind((socket.gethostname(), 1234))
7

Không trông thật nóng bỏng. Vì vậy, bạn có thể nhận ra rằng thêm tối đa 8 ký tự theo nghĩa đen, vì vậy mỗi byte là một ký tự. Tại sao không. quay lại 1024? . Tại sao lại làm việc trong bộ đệm?

Tại một số thời điểm, bất kể bạn đặt số lượng nào, nhiều ứng dụng sử dụng ổ cắm cuối cùng sẽ muốn gửi một lượng byte vượt xa kích thước bộ đệm. Thay vào đó, có lẽ chúng ta cần xây dựng chương trình của mình từ đầu để thực sự chấp nhận toàn bộ thông báo trong các đoạn của bộ đệm, ngay cả khi thường chỉ có một đoạn. Chúng tôi làm điều này chủ yếu để quản lý bộ nhớ. Các tính toán tùy thuộc vào ứng dụng có thể khác nhau và bạn có thể tự do chơi với kích thước bộ đệm sau này. Điều duy nhất tôi có thể chắc chắn hứa là. bạn cần lập kế hoạch ngay từ đầu để xử lý các giao tiếp theo khối

Đối với khách hàng của chúng tôi, làm thế nào chúng tôi có thể làm điều này? . Dữ liệu sẽ đến dưới dạng luồng, vì vậy, thực sự, việc xử lý việc này đơn giản như thay đổi tệp

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 của chúng tôi thành

s.bind((socket.gethostname(), 1234))
8

Vì vậy, hiện tại, chúng tôi sẽ nhận dữ liệu này và in nó thành từng khối. Nếu chúng ta chạy

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 bây giờ, chúng ta sẽ thấy

s.bind((socket.gethostname(), 1234))
9

Bạn cũng nên lưu ý rằng

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 của chúng tôi không còn tồn tại. Kết nối này hiện vẫn mở. Điều này là do vòng lặp
while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
8 của chúng tôi. Chúng tôi có thể sử dụng
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5 trên ổ cắm để đóng nó nếu muốn. Chúng tôi có thể làm điều này trên máy chủ hoặc trên máy khách. hoặc cả hai. Có lẽ nên chuẩn bị cho trường hợp kết nối bị ngắt hoặc bị đóng vì bất kỳ lý do gì. Ví dụ: chúng tôi có thể đóng kết nối sau khi gửi tin nhắn của mình trên máy chủ

s.listen(5)
8

s.listen(5)
0

Tuy nhiên, nếu chúng tôi chạy chương trình này, chúng tôi sẽ thấy

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 của mình sau đó spam ra một loạt dữ liệu không có gì, bởi vì dữ liệu mà nó nhận được, không có gì. Nó trống rỗng. 0 byte, nhưng chúng tôi vẫn yêu cầu nó in ra những gì nó nhận được, ngay cả khi không có gì. Chúng tôi có thể khắc phục điều đó

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2

s.listen(5)
1

Vì vậy, bây giờ chúng tôi đang xem qua toàn bộ thông báo. Khi chúng tôi kết thúc, điều mà chúng tôi đang chú ý bằng cách nhận 0 byte, chúng tôi sẽ ngắt và sau đó trả lại tin nhắn. Điều này sau đó kết thúc

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2. Bây giờ, khách hàng có thể muốn duy trì kết nối. Làm thế nào chúng ta có thể làm điều đó?

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2

s.listen(5)
2

Tất nhiên, có lẽ một lần nữa chúng ta nên đảm bảo rằng

s.connect((socket.gethostname(), 1234))
2 có nội dung nào đó trước khi in ra

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2

s.listen(5)
3

Điều này hoạt động, nhưng chúng tôi có vấn đề. Điều gì xảy ra khi chúng tôi ngừng đóng ổ cắm máy khách ở phía máy chủ? . Tại sao lại thế này?

TCP là một giao tiếp *stream*. vậy làm thế nào để chúng ta thực sự biết khi nào một tin nhắn đang thực sự xảy ra? . Có nhiều cách để chúng ta có thể làm điều này. Một cách phổ biến là sử dụng một loại tiêu đề luôn dẫn đầu thông điệp của chúng tôi. Chúng tôi cũng có thể sử dụng một số loại chân trang, nhưng điều này có thể gây rắc rối nếu ai đó tìm hiểu về phương pháp của chúng tôi

Gửi trong lập trình socket là gì?

Hàm send() gửi dữ liệu trên ổ cắm với ổ cắm mô tả . Cuộc gọi send() áp dụng cho tất cả các ổ cắm được kết nối. Thông số Mô tả ổ cắm. Bộ mô tả ổ cắm. tin nhắn.

Socket socket() trong python là gì?

Ổ cắm và API ổ cắm được dùng để gửi tin nhắn qua mạng . Họ cung cấp một hình thức giao tiếp giữa các quá trình (IPC). Mạng có thể là mạng logic, cục bộ với máy tính hoặc mạng được kết nối vật lý với mạng bên ngoài, có kết nối riêng với các mạng khác.

Làm cách nào để gửi dữ liệu từ máy khách đến máy chủ trong ổ cắm?

Tạo socket với lệnh gọi hệ thống socket(). Khởi tạo cấu trúc địa chỉ ổ cắm theo máy chủ và kết nối ổ cắm với địa chỉ của máy chủ bằng lệnh gọi hệ thống connect(). Nhận và gửi dữ liệu bằng recv() và send() . Đóng kết nối bằng cách gọi hàm close().

Làm cách nào để nhận dữ liệu từ ổ cắm trong python?

Nếu bạn đang viết một chương trình socket bằng python để giao tiếp với một số máy hoặc máy chủ từ xa để nhận dữ liệu, thì bạn phải sử dụng hàm recv() to receive data on a socket. The recv() can receive only a specified number of bytes into a string buffer.