1、TCP連結
TCP是一種面向連接配接的、可靠的、基于位元組流的傳輸層通信協定。是以在進行TCP連結時首先要開啟伺服器端口。
TCP服務端一般有幾個步驟:
① sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 建立套接字,第一個參數為套接字家族AF_INET:基于網絡的套接字家族;第二個參數SOCK_STREAM:基于TCP協定的通信類型。建立時不帶參數預設建立基于TCP協定的網絡連結。
② sk.bind(address) 綁定本機位址與端口号,address:元組,第一個元素為本機ip位址,第二個元素為端口号。
③ sk.listen() 開始監聽TCP傳傳入連結接。
④ sock, addr = sk.accept() 接收成功連結的TCP并傳回元組(sock, addr),元組第一個元素為新的套接字,負責與連結成功的用戶端通信,元組第二個元素為位址,包含IP,與端口号,即 addr = (ip, port)
⑤ sock.recv(bufsize) bufsize 指定最大接收位元組數,傳回一個bytes對象,即位元組數組。沒有資料接收時線程在此堵塞
⑥ sock.send(bytes) 将bytes發送到tcp用戶端,傳回發送的位元組數,接收和發送可以并發執行
⑦ sock.close() 将與用戶端通信的套接字關閉,關閉後不能與該用戶端進行通信
⑧ sk.close() 将服務端監聽套接字關閉,關閉後将不能接收新的連結
TCP用戶端一般有幾個步驟:
① sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 建立套接字
② sk.connect(("127.0.0.1", 8899)) 連結用戶端
③ sk.send(bytes) 将bytes發送到伺服器,傳回發送的位元組數
④ msg = sk.recv(bufsize) 接收資料,接收和發送可以并發執行
⑤ sk.close() 關閉套接字
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 import socket
2
3
4 def fn(conn):
5 msg = conn.recv(1024).decode("utf-8")
6 print("服務端收到>>>", msg)
7 conn.send(msg.encode("utf-8"))
8 print("服務端發送消息到用戶端>>>", msg)
9
10
11 if __name__ == "__main__":
12 sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
13 sk.bind(("127.0.0.1", 8899))
14 sk.listen()
15 while True:
16 conn, addr = sk.accept()
17 print("已連接配接伺服器-->", addr)
18 fn(conn)
19 sk.close()
20
21
22 # 輸出結果
23 已連接配接伺服器--> ('127.0.0.1', 55921)
24 服務端收到>>> hhh
25 服務端發送消息到用戶端>>> hhh
服務端
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 import socket
2
3 sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
4 sk.connect(("127.0.0.1", 8899))
5 msg = input()
6 sk.send(msg.encode("utf-8"))
7 print("用戶端發送的内容>>>", msg)
8 msg = sk.recv(1024).decode("utf-8")
9 print("用戶端收到>>>", msg)
10 sk.close()
11
12
13 # 輸出結果
14 hhh
15 用戶端發送的内容>>> hhh
16 用戶端收到>>> hhh
用戶端
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 import socket
2 from threading import Thread
3
4
5 def fn(conn):
6 msg = conn.recv(1024).decode("utf-8")
7 print("服務端收到>>>", msg)
8 conn.send(msg.encode("utf-8"))
9 print("服務端發送消息到用戶端>>>", msg)
10
11
12 if __name__ == "__main__":
13 sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
14 sk.bind(("127.0.0.1", 8899))
15 sk.listen()
16 while True:
17 conn, addr = sk.accept()
18 print("已連接配接伺服器-->", addr)
19 t = Thread(target=fn, args=(conn,))
20 t.start()
21 sk.close()
22
23
24 # 輸出結果已連接配接伺服器--> ('127.0.0.1', 55938)
25 已連接配接伺服器--> ('127.0.0.1', 55939)
26 已連接配接伺服器--> ('127.0.0.1', 55940)
27 服務端收到>>> 111
28 服務端發送消息到用戶端>>> 111
29 服務端收到>>> 222
30 服務端發送消息到用戶端>>> 222
31 服務端收到>>> 333
32 服務端發送消息到用戶端>>> 333
服務端(多線程)
2、UDP連接配接
udp服務端連接配接步驟:
② sk.bind(addr) 綁定指定端口和位址,服務端必須綁定,不然用戶端無法知道服務端的端口号。用戶端可不進行綁定程式運作時随機綁定一個端口号
③ recv_msg, recv_addr = sk.recvfrom(bufsize) 接收資料,沒有資料接收時線程在此堵塞
④ sk.sendto(bytes, recv_addr) 發送資料,udp每一次發送資料都需要指定位址,發送與接收可以并發執行
⑤ sk.close() 關閉socket
udp用戶端連接配接步驟:
② sk.sendto(bytes, recv_addr) 發送資料,傳回發送的位元組數,udp每一次發送資料都需要指定位址,發送與接收可以并發執行
④ sk.close() 關閉socket
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 import socket
2
3 print("-----server------")
4
5 addr = ("127.0.0.1", 8899)
6 sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
7 sk.bind(addr)
8
9 recv_msg, recv_addr = sk.recvfrom(1024)
10 print("服務端收到>>>", recv_msg.decode("utf-8"), recv_addr)
11 msg = "AAA"
12 sk.sendto(msg.encode("utf-8"), recv_addr)
13 print("服務端發送>>>", msg)
14
15 sk.close()
16
17
18 # 輸出結果
19 -----server------
20 服務端收到>>> BBB ('127.0.0.1', 55802)
21 服務端發送>>> AAA
UDP server
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 import socket
2
3 print("-----client------")
4
5 server_addr = ("127.0.0.1", 8899)
6 sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
7
8 msg = "BBB"
9 sk.sendto(msg.encode("utf-8"), server_addr)
10 print("用戶端發送>>>", msg)
11 recv_msg, recv_addr = sk.recvfrom(1024)
12
13 print("用戶端發送>>>", recv_msg.decode("utf-8"), recv_addr)
14
15 sk.close()
16
17
18 # 輸出結果
19 -----client------
20 用戶端發送>>> BBB
21 用戶端發送>>> AAA ('127.0.0.1', 8899)
UDP client