Python3 Socket

Socket

socket介紹

socket意爲套接字,是應用層與傳輸層TCP/IP,UDP之間通訊的中間軟件抽象層,它是一組接口。使用時只需遵循socket的格式與規定去編程,讓socket組織數據以符合TCP/UDP協議進行數據的傳輸。python

img

socket的工做流程

img

先從服務端提及,服務端先初始化socket --> 爲此socket綁定端口(bind) --> 監聽此端口(listen) --> 調用accept阻塞socket,直到有客戶端鏈接 --> 若是此時客戶端鏈接成功(connect),即與服務端完整創建鏈接,便可開始發送數據請求(write) --> 服務器端接收請求並處理請求(read),而後把迴應數據發送給客戶端(write) --> 客戶端讀取響應內容(read) --> 關閉鏈接,交互結束(close)編程

scoket初始化->socket.socket()

socket.socket(socket_family,socket_type,protocal=0)緩存

socket_family

AF_INET(ipv4)
AF_INET6 (ipv6)
AF_UNIX(UNIX之間通訊,絕對路徑名)

socket_type

#   SOCK_STREAM 提供有序的、可靠的、雙向的和基於鏈接的字節流服務,當使用Internet地址族時使用TCP;通常爲面向鏈接的TCP

#   SOCK_DGRAM 支持無鏈接的、不可靠的和使用固定大小(一般很小)緩衝區的數據報服務,當使用Internet地址族使用UDP;通常爲非鏈接的UDP

#   SOCK_RAW 原始套接字,容許對底層協議如IP或ICMP進行直接訪問,能夠用於自定義協議的開發。

protocal

#	IPPROTO_TCP,TCP協議

# 	IPPROTO_UDP,UPD協議

# 	0,若是指定爲0,表示由內核根據so_type指定默認的通訊協議

TCP/IP+ipv4

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

服務端套接字

s.bind()

用於綁定(主機/ip,端口)到socket套接字, 在AF_INET下,以元組(host,port)的形式表示地址。服務器

s.bind(('xxx.xxx.xxx.xxx',port))

s.listen()

開始TCP監聽。backlog指定在拒絕鏈接以前,操做系統能夠掛起的最大鏈接數量。該值至少爲1,大部分應用程序設爲5就能夠了。socket

ps:udp不支持listen()tcp

s.listen(5)

s.accept()

被動接受TCP客戶端鏈接,(阻塞式)等待鏈接的到來函數

ps: udp不支持大數據

conn,addr = s.accept()

關於accept()返回值在官方文檔是這麼說的this

The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection.

有兩個返回值conn和address,第一個返回值爲新的 socket 對象可用於發送和接受數據,形式大體以下操作系統

<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.124.141', 12345), raddr=('192.168.124.1', 15563)>

address爲一個元組,元組包含遠端鏈接的ip地址和端口,形如

('192.168.124.1', 15563)

客戶端套接字

s.connect()

主動初始化TCP服務器鏈接。通常address的格式爲元組(主機/ip,port),若是鏈接出錯,返回socket.error錯誤。

s.connect(('192.168.124.1',22222))

s.connect_ex()

connect()函數的擴展版本,出錯時返回出錯碼,而不是拋出異常

公共用途的套接字函數

s.recv()

socket.recv(bufsize[, flags])

從套接字接收數據。返回值是表示接收到的數據的bytes對象。bufsize指定一次接收的最大數據量。通常爲1024

s.recv(1024)

s.send()

發送數據,將數據發送到socket套接字。(send在待發送數據量大於己端緩存區剩餘空間時,數據丟失,不會發完)

s.send('This is Socket Client!'.encode('utf-8'))

s.sendall()

發送完整的TCP數據(本質就是循環調用send,sendall在待發送數據量大於己端緩存區剩餘空間時,數據不丟失,循環調用send直到發完)

s.close()

關閉socket 套接字

簡單例子 TCP鏈接

SocketServer.py

#!/usr/bin/python3
#-*- coding:UTF-8 -*-

import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
phone.bind(('192.168.124.141',12345)) 

phone.listen(5) 

conn,addr=phone.accept() 
print(conn,addr)
print('Remote IP Address is',addr)

client_msg=conn.recv(1024) 
print('client msg: %s' %client_msg)
conn.send(client_msg。upper()) 

conn.close()
s.close()

SocketClient.py

import socket

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

s.connect(('192.168.124.141', 12345))

s.send('this is socket client!'.encode('utf-8'))

res_msg = s.recv(1024)
print(res_msg)

s.close

服務端

image-20201124233020283

客戶端

image-20201124233105709

簡單例子UDP鏈接

SocketServer.py

#!/usr/bin/python3
#-*- coding:UTF-8 -*-

import socket


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

ip = '192.168.124.141'
port = 12346

s.bind((ip,port))

recv_data,addr = s.recvfrom(1024)
print('Client Send Message: %s' %recv_data)

server_send_data = 'this is server!!!'

s.sendto(server_send_data.encode(),addr)

s.close()

SocketClient.py

import socket


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

s.sendto('this is socket client!!!'.encode('utf-8'),('192.168.124.141',12346))

res_msg,addr = s.recvfrom(1024)

print(res_msg)

s.close()

服務端

image-20201125001423390

客戶端

image-20201125001439186

相關文章
相關標籤/搜索