一、什么是socket?
socket是一個模塊, 又稱套接字,用來封裝 互聯網協議(應用層以下的層)。
二、為什么要有socket?
socket可以實現互聯網協議 應用層以下的層 的工作,提高開發效率。
三、怎么使用socket?
import socket
寫socket套接字:
- Client
- Server
使用如下:client.py
'''
啟動服務端后再啟動客戶端
'''
import socket
#1.買手機
client = socket.socket() #拿到一個手機對象
#2.撥號
client.connect(('127.0.0.1',9527)) #客戶端的ip和port必須與服務器一致
print('client is running')
#3.通信循環
#講話給對方聽
while True:
send_data = input('客戶端>>>:')
client.send(send_data.encode('utf-8')) #只能發bytes類型
data = client.recv(1024)
if data.decode('utf-8') == 'q':
break
if len(data) == 0:
break
print(data.decode('utf-8'))
#4.斷開連接
client.close()
server.py
'''
先啟動套接字服務端
注意:
客戶端發送一次消息,服務端就得接受一次,再發送消息。
'''
import socket
#1.買手機
server = socket.socket() #拿到一個手機對象
# print(server) # server是用來收發鏈接請求,建立鏈接
#2.綁手機卡
server.bind(('127.0.0.1',9527)) #0-65535 #本地回環地址 ---》'127.0.0.1'
#3.開機(半連接池)
server.listen(5) #同一時刻,最大請求數為5個 實際==6
print('sever is running')
#4.等待電話請求
#conn:指的是服務端往客戶端的管道
#conn,addr = server.accept() #(雙向連接的套接字對象,存放客戶端IP和端口的小元組)
# print(conn) #conn代表雙向鏈接,用來收發鏈接
#5.循環實現可接受多個用戶訪問
while True:
#等待電話接入 --->接入客戶端
# conn: 指的是服務端往客戶端的管道
conn,addr = server.accpt()
print(addr)
#實現循環通信
while True:
try: #監聽代碼塊是否有異常出現
# 接受對方講話的內容
# data --->客戶端發送過來的消息
data = conn.recv(1024) #1024接受的最大字節數bytes
if len(data) == 0:
break
if data.decode('utf-8') == 'q':
break
print(data.decode('utf-8'))
send_data = input('服務器>>>:')
#服務器往客戶端發送消息
conn.send(send_data.encode('utf-8'))
# 捕獲異常信息,並打印 # e: 報錯信息
except Exception as e:
print(e)
break
#6.掛電話連接
conn.close()
四、並發實現套接字通信
版本一:簡單版
client.py
import socket
client = socket.socket()
client.connect(('127.0.0.1',9500))
print('Client is running')
while True:
msg = input('客戶端:').encode('utf-8')
client.send(msg)
data = client.recv(1024)
print(data)
server.py
import socket
from threading import Thread
#封裝成函數
def communicate(conn):
while True: #通信循環
try:
data = conn.recv(1024)
if len(data) == 0:
break
print(data.decode('utf-8'))
conn.send('好啊'.encode('utf-8'))
except Exception as e:
print(e)
break
conn.close()
def server(backlog=5):
server = socket.socket()
server.bind(('127.0.0.1',9500))
server.listen(backlog)
while True: #鏈接循環
conn,addr = server.accept()
print(addr)
t = Thread(target=communicate,args=(conn,))
t.start()
if __name__ == '__main__':
t = Thread(target=server)
t.start()
版本二:半連接池版
client.py
import socket
client = socket.socket()
client.connect(('127.0.0.1',9500))
print('Client is running')
while True:
msg = input('客戶端:').encode('utf-8')
client.send(msg)
data = client.recv(1024)
print(data)
server.py
import socket
from concurrent.futures import ThreadPoolExecutor
server = socket.socket()
server.bind(('127.0.0.1',9500))
server.listen(5)
#封裝成一個函數
def run(conn):
while True:
try:
data = conn.recv(1024)
if len(data) == 0:
break
print(data.decode('utf-8'))
conn.send('好啊'.encode('utf-8'))
except Exception as e:
print(e)
break
conn.close()
if __name__ == '__main__':
print('Server is running')
pool = ThreadPoolExecutor(100)
while True:
conn,addr = server.accept()
pool.submit(run,conn)