Socket và các phương thức của nó

Sockets là điểm cuối của một kênh giao tiếp hai chiều. Chúng có thể giao tiếp trong một quá trình, giữa các quá trình trên cùng một máy hoặc giữa các quá trình trên các máy khác nhau. Một lưu ý tương tự, ổ cắm mạng là một điểm cuối trong luồng giao tiếp giữa hai chương trình chạy trên mạng máy tính chẳng hạn như Internet. Nó hoàn toàn là một thứ ảo và không có nghĩa là bất kỳ phần cứng nào. Ổ cắm mạng có thể được xác định bằng sự kết hợp duy nhất của địa chỉ IP và số cổng. Các ổ cắm mạng có thể được triển khai trên một số loại kênh khác nhau như TCP, UDP, v.v.

Các thuật ngữ khác nhau liên quan đến socket được sử dụng trong lập trình mạng như sau:

Miền

Miền là họ các giao thức được sử dụng làm cơ chế truyền tải. Các giá trị này là các hằng số như AF_INET, PF_INET, PF_UNIX, PF_X25, v.v.

Kiểu

Loại có nghĩa là loại giao tiếp giữa hai điểm cuối, thường là SOCK_STREAM cho các giao thức hướng kết nối và SOCK_DGRAM cho các giao thức không kết nối.

Giao thức

Điều này có thể được sử dụng để xác định một biến thể của giao thức trong một miền và loại. Giá trị mặc định của nó là 0. Giá trị này thường bị bỏ qua.

Tên máy chủ

Điều này hoạt động như mã nhận dạng của giao diện mạng. Tên máy chủ lưu trữ không được là một chuỗi, một địa chỉ tứ phân chấm hoặc một địa chỉ IPV6 trong ký hiệu dấu hai chấm (và có thể là dấu chấm).

Hải cảng

Mỗi máy chủ lắng nghe các máy khách gọi trên một hoặc nhiều cổng. Một cổng có thể là số cổng Fixnum, một chuỗi chứa số cổng hoặc tên của một dịch vụ.

Mô-đun Socket của Python để lập trình Socket

Để thực hiện lập trình socket trong python, chúng ta cần sử dụng mô-đun Socket. Sau đây là một cú pháp đơn giản để tạo một Socket:

import socket
s = socket.socket (socket_family, socket_type, protocol = 0)

Ở đây, chúng ta cần nhập thư viện ổ cắm và sau đó tạo một ổ cắm đơn giản. Sau đây là các thông số khác nhau được sử dụng khi tạo ổ cắm:

  • socket_family - Đây là AF_UNIX hoặc AF_INET, như đã giải thích trước đó.

  • socket_type - Đây là SOCK_STREAM hoặc SOCK_DGRAM.

  • protocol - Điều này thường được bỏ qua, mặc định là 0.

Phương pháp Socket

Trong phần này, chúng ta sẽ tìm hiểu về các phương thức socket khác nhau. Ba phương pháp socket khác nhau được mô tả dưới đây:

  • Phương thức ổ cắm máy chủ
  • Phương thức Socket Máy khách
  • Các phương pháp ổ cắm chung

Phương thức ổ cắm máy chủ

Trong kiến ​​trúc máy khách-máy chủ, có một máy chủ tập trung cung cấp dịch vụ và nhiều máy khách nhận dịch vụ từ máy chủ tập trung đó. Các máy khách cũng thực hiện yêu cầu đối với máy chủ. Một số phương pháp socket máy chủ quan trọng trong kiến ​​trúc này như sau:

  • socket.bind() - Phương thức này liên kết địa chỉ (tên máy, số cổng) vào socket.

  • socket.listen()- Phương pháp này về cơ bản lắng nghe các kết nối được thực hiện với ổ cắm. Nó khởi động trình nghe TCP. Backlog là một đối số của phương thức này chỉ định số lượng tối đa các kết nối được xếp hàng đợi. Giá trị nhỏ nhất của nó là 0 và giá trị lớn nhất là 5.

  • socket.accept()- Điều này sẽ chấp nhận kết nối máy khách TCP. Cặp (conn, address) là cặp giá trị trả về của phương thức này. Ở đây, conn là một đối tượng socket mới được sử dụng để gửi và nhận dữ liệu trên kết nối và address là địa chỉ liên kết với socket. Trước khi sử dụng phương thức này, phương thức socket.bind () và socket.listen () phải được sử dụng.

Phương thức Socket Máy khách

Máy khách trong kiến ​​trúc máy khách-máy chủ yêu cầu máy chủ và nhận các dịch vụ từ máy chủ. Đối với điều này, chỉ có một phương pháp dành riêng cho khách hàng -

  • socket.connect(address)- phương pháp này chủ động kết nối máy chủ thân mật hay nói cách đơn giản phương pháp này kết nối máy khách với máy chủ. Địa chỉ đối số đại diện cho địa chỉ của máy chủ.

Các phương pháp ổ cắm chung

Ngoài các phương thức socket của máy khách và máy chủ, có một số phương thức socket chung, rất hữu ích trong lập trình socket. Các phương pháp ổ cắm chung như sau:

  • socket.recv(bufsize)- Như tên của nó, phương thức này nhận thông điệp TCP từ socket. Đối số bufsize là viết tắt của kích thước bộ đệm và xác định dữ liệu tối đa mà phương thức này có thể nhận bất kỳ lúc nào.

  • socket.send(bytes)- Phương pháp này được sử dụng để gửi dữ liệu đến ổ cắm được kết nối với máy từ xa. Đối số byte sẽ cung cấp số byte được gửi đến socket.

  • socket.recvfrom(data, address)- Phương thức này nhận dữ liệu từ socket. Giá trị hai cặp (dữ liệu, địa chỉ) được trả về bằng phương thức này. Dữ liệu xác định dữ liệu nhận được và địa chỉ xác định địa chỉ của socket gửi dữ liệu.

  • socket.sendto(data, address)- Như tên của nó, phương thức này được sử dụng để gửi dữ liệu từ socket. Giá trị hai cặp (dữ liệu, địa chỉ) được trả về bằng phương thức này. Dữ liệu xác định số byte được gửi và địa chỉ chỉ định địa chỉ của máy từ xa.

  • socket.close() - Phương pháp này sẽ đóng ổ cắm.

  • socket.gethostname() - Phương thức này sẽ trả về tên của máy chủ.

  • socket.sendall(data)- Phương pháp này gửi tất cả dữ liệu đến ổ cắm được kết nối với máy từ xa. Nó sẽ chuyển dữ liệu một cách bất cẩn cho đến khi xảy ra lỗi và nếu nó xảy ra thì nó sẽ sử dụng phương thức socket.close () để đóng socket.

Chương trình thiết lập kết nối giữa máy chủ và máy khách

Để thiết lập kết nối giữa máy chủ và máy khách, chúng ta cần viết hai chương trình Python khác nhau, một chương trình dành cho máy chủ và chương trình còn lại dành cho máy khách.

Chương trình phía máy chủ

Trong chương trình socket phía máy chủ này, chúng tôi sẽ sử dụng socket.bind()phương thức liên kết nó với một địa chỉ IP và cổng cụ thể để nó có thể lắng nghe các yêu cầu đến trên IP và cổng đó. Sau đó, chúng tôi sử dụngsocket.listen()phương pháp đặt máy chủ vào chế độ lắng nghe. Con số, giả sử 4, là đối số củasocket.listen()phương pháp này có nghĩa là 4 kết nối được tiếp tục chờ nếu máy chủ bận và nếu ổ cắm thứ 5 cố gắng kết nối thì kết nối bị từ chối. Chúng tôi sẽ gửi một tin nhắn cho khách hàng bằng cách sử dụngsocket.send()phương pháp. Cuối cùng, chúng tôi sử dụngsocket.accept()socket.close()phương thức khởi tạo và đóng kết nối tương ứng. Sau đây là một chương trình phía máy chủ -

import socket
def Main():
   host = socket.gethostname()
   port = 12345
   serversocket = socket.socket()
   serversocket.bind((host,port))
   serversocket.listen(1)
   print('socket is listening')
   
   while True:
      conn,addr = serversocket.accept()
      print("Got connection from %s" % str(addr))
      msg = 'Connecting Established'+ "\r\n"
      conn.send(msg.encode('ascii'))
      conn.close()
if __name__ == '__main__':
   Main()

Chương trình phía khách hàng

Trong chương trình socket phía máy khách, chúng ta cần tạo một đối tượng socket. Sau đó, chúng tôi sẽ kết nối với cổng mà máy chủ của chúng tôi đang chạy - 12345 trong ví dụ của chúng tôi. Sau đó, chúng tôi sẽ thiết lập kết nối bằng cách sử dụngsocket.connect()phương pháp. Sau đó, bằng cách sử dụngsocket.recv(), máy khách sẽ nhận được thông báo từ máy chủ. Cuối cùng,socket.close() phương thức sẽ đóng máy khách.

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

host = socket.gethostname()
port = 12345

s.connect((host, port))
msg = s.recv(1024)

s.close()
print (msg.decode('ascii'))

Bây giờ, sau khi chạy chương trình phía máy chủ, chúng ta sẽ nhận được kết quả sau trên terminal:

socket is listening
Got connection from ('192.168.43.75', 49904)

Và sau khi chạy chương trình phía máy khách, chúng ta sẽ nhận được kết quả sau trên thiết bị đầu cuối khác:

Connection Established

Xử lý ngoại lệ ổ cắm mạng

Có hai khối cụ thể là tryexceptcó thể được sử dụng để xử lý các ngoại lệ về ổ cắm mạng. Sau đây là một tập lệnh Python để xử lý ngoại lệ:

import socket
host = "192.168.43.75"
port = 12345
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

try:
   s.bind((host,port))
   s.settimeout(3)
   data, addr = s.recvfrom(1024)
   print ("recevied from ",addr)
   print ("obtained ", data)
   s.close()
except socket.timeout :
   print ("No connection between client and server")
   s.close()

Đầu ra

Chương trình trên tạo ra kết quả sau:

No connection between client and server

Trong đoạn mã trên, đầu tiên chúng ta tạo một đối tượng socket. Tiếp theo là cung cấp địa chỉ IP máy chủ và số cổng mà máy chủ của chúng tôi đang chạy - 12345 trong ví dụ của chúng tôi. Sau đó, khối try được sử dụng và bên trong nó bằng cách sử dụngsocket.bind(), chúng tôi sẽ cố gắng liên kết địa chỉ IP và cổng. Chúng tôi đang sử dụngsocket.settimeout()phương pháp đặt thời gian chờ cho khách hàng, trong ví dụ của chúng tôi, chúng tôi đang đặt 3 giây. Khối ngoại trừ được sử dụng sẽ in thông báo nếu kết nối không được thiết lập giữa máy chủ và máy khách.