目錄
目錄
1.socket簡介
2.創(chuàng)建socket
2.1創(chuàng)建UDPSocket
2.2創(chuàng)建TCPSocket
3.使用UDPSocket發(fā)送數(shù)據(jù)并接收
4.使用UDPSocket發(fā)送廣播
5.UDPSocket聊天器 (多線程實現(xiàn)消息的收發(fā)功能)
6.使用TCPSocket建立客戶端
7.使用TCPSocket建立服務端
1.socket簡介
? ? ? ?socket(簡稱:套接字),是支持TCP和UDP(網(wǎng)絡傳輸方式)網(wǎng)絡通信的基本操作單元,可以看做是不同主機之間的進程進行雙向通信的端點,簡單的說就是通信的兩方的一種約定,用套接字中的相關(guān)函數(shù)來完成通信過程。
????????它能實現(xiàn)不同主機間的進程間通信,我們網(wǎng)絡上各種各樣的服務大多都是基于socket來完成通信的,例如瀏覽的網(wǎng)頁、qq聊天、收發(fā)email等等。
2.創(chuàng)建socket
? ? ? ? socket起源于Unix,而Unix/Linux基本哲學之一就是“一切皆文件”,對于文件用打開、讀寫、關(guān)閉模式來操作。socket就是該模式的一個實現(xiàn),socket即是一種特殊的文件,一些socket類就是對其進行的操作(讀寫IO、打開、關(guān)閉)
在Python中使用socket模塊的socket類來完成:
import socket
socket.socket(AddressFamily, Type)
說明:
? ? ? ? 1. 參數(shù):AddressFamily(地址簇)
? ? ? ? socket.AF_INET IPv4? ????????(默認)? ? ? ?
????????socket.AF_INET6 IPv6
? ? ? ? socket.AF_UNIX? ? ? ? ? ? ? ? ? ? 只能夠用于單一的Unix系統(tǒng)進程通信
? ? ? ? 2.參數(shù):Type(類型)
? ? ? ? socket.SOCK_STREAM? ? ? ? 流式socket,for TCP(默認)
? ? ? ? socket.SOCK_DGRAM? ? ? ? ?數(shù)據(jù)報式socket,for UDP
2.1創(chuàng)建UDPSocket
import socket
# 使用IPv4 UDP方式來創(chuàng)建套接字
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 參數(shù)socket.AF_INET表示使用IPv4,參數(shù)socket.SOCK_DGRAM表示使用UDP
# 省略數(shù)據(jù)傳遞過程
# 關(guān)閉套接字
udp_socket.close()
2.2創(chuàng)建TCPSocket
import socket
# 使用IPv4 TCP方式來創(chuàng)建套接字
tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 參數(shù)socket.AF_INET表示使用IPv4,參數(shù)socket.SOCK_STREAM表示使用TCP
# 省略數(shù)據(jù)傳遞過程
# 關(guān)閉套接字
tcp_socket.close()
3.使用UDPSocket發(fā)送數(shù)據(jù)并接收
核心方法:
????????socket.sendto
sendto方法的參數(shù):
? ? ? ? 1.要發(fā)送的二進制數(shù)據(jù)? ? ? ? (使用.encode()方法可以將字符串轉(zhuǎn)為二進制)
? ? ? ? 2.接收者的ip地址和端口號? (元組類型:("127.0.0.1", 8080))
import socket
# 使用IPv4 UDP方式來創(chuàng)建套接字
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#2.綁定一個本地信息
localaddr = ("192.168.68.196",8081)
udp_socket.bind(localaddr)
# 發(fā)送數(shù)據(jù)
udp_socket.sendto("hello".encode(),("192.168.68.196",8080))
# 關(guān)閉套接字
udp_socket.close()
接收數(shù)據(jù)(兩種方式):
? ? ? ? 方式一:通過網(wǎng)絡調(diào)試助手接收(下載地址:NetAssist.exe下載)
對于接收到的中文是亂碼的問題:
????????可能是由于encode()方法默認使用UTF-8的編碼方式
.encode()
?將其改為gb2312編碼方式:
.encode("gb2312")
如下圖標注部分為修改編碼方式前后的對比:?
????????方式二:通過python代碼制作一個接收端
import socket
def main():
#1.創(chuàng)建套接字
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#2.綁定一個本地信息
localaddr = ("192.168.68.196",8080)
udp_socket.bind(localaddr)
#3.接收數(shù)據(jù)
while True:
recv_data = udp_socket.recvfrom(1024) #1024表示每次接收1024字節(jié)
recv_msg = recv_data[0] #存儲接收到的數(shù)據(jù)
send_addr = recv_data[1]#存儲發(fā)送方的地址信息
#4.打印接收到的數(shù)據(jù)
# print(recv_data)
print("%s:%s" % (str(send_addr),recv_msg.decode("gb2312")) )
#5.關(guān)閉套接字
udp_socket.close()
if __name__ == "__main__":
main()
4.使用UDPSocket發(fā)送廣播
????????廣播地址(Broadcast Address)是專門用于同時向網(wǎng)絡中所有工作站進行發(fā)送的一個地址。在使用TCP/IP 協(xié)議的網(wǎng)絡中,主機標識段host ID 為全1 的IP 地址為廣播地址,廣播的分組傳送給host ID段所涉及的所有計算機。例如,對于10.1.1.0 (255.0.0.0 )網(wǎng)段,其廣播地址為10.255.255.255 (255 即為二進制的11111111 ),當發(fā)出一個目的地址為10.255.255.255 的分組(封包)時,它將被分發(fā)給該網(wǎng)段上的所有計算機。
import socket
# 使用IPv4 UDP方式來創(chuàng)建套接字
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#2.綁定一個本地信息
localaddr = ("192.168.68.196",8081)
udp_socket.bind(localaddr)
# 設置允許發(fā)送廣播
udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
# 發(fā)送信息
udp_socket.sendto("大家好,我宣布個事兒".encode("gb2312"), ("255.255.255.255", 8080))
# 關(guān)閉套接字
udp_socket.close()
運行結(jié)果:(此時處于同一網(wǎng)段,端口為8080的客戶端應該都能接收到廣播信息)
5.UDPSocket聊天器 (多線程實現(xiàn)消息的收發(fā)功能)
實現(xiàn)效果:
python UDPSocket聊天器 (多線程實現(xiàn)消息的收發(fā)功能)
代碼:
import socket
from threading import Thread,Lock
def send_msg(udp_socket):
"""發(fā)送信息的函數(shù)"""
while True:
input_msg = input("請輸入聊天內(nèi)容:\n") # 用戶輸入一些信息
udp_socket.sendto(input_msg.encode("gb2312"), ("192.168.68.196", 8081))
def recv_msg(udp_socket):
"""接收信息的函數(shù)"""
while True:
recv_data, tuple_ip_port = udp_socket.recvfrom(1024)
recv_text = recv_data.decode("gb2312")
print("接受到[%s]的信息:%s" % (str(tuple_ip_port), recv_text))
def main():
# 創(chuàng)建套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 綁定端口
udp_socket.bind(("", 8080))
# 接收信息
t1 = Thread(target=recv_msg, args=(udp_socket,))
t1.start()
# 發(fā)送信息
t2 = Thread(target=send_msg, args=(udp_socket,))
t2.start()
# # 關(guān)閉套接字
# udp_socket.close()
if __name__ == '__main__':
main()
6.使用TCPSocket建立客戶端
import socket
# 創(chuàng)建套接字
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立連接
tcp_client_socket.connect(("192.168.68.196", 8081))
# 發(fā)送數(shù)據(jù)
tcp_client_socket.send("你好".encode("gb2312"))
# 接收數(shù)據(jù)
recv_data = tcp_client_socket.recv(1024).decode("gb2312")
print(recv_data)
# 關(guān)閉套接字
tcp_client_socket.close()
7.使用TCPSocket建立服務端
? ? ? ? ·能夠?qū)崿F(xiàn)一個客戶端發(fā)來的多條信息
? ? ? ? ·能夠接收多個客戶端連接
import socket
from threading import Thread
def new_client_connect(new_client_socket, client_ip_port):
while True:
# 收發(fā)數(shù)據(jù)
recv_data = new_client_socket.recv(1024)
if len(recv_data) != 0:
recv_text = recv_data.decode("gb2312")
print("接收到[%s]的信息:%s" % (str(client_ip_port), recv_text))
else:
print("客戶端斷開連接")
break
# # 關(guān)閉連接
# new_client_socket.close() # 表示斷開與當前的客戶端的通信
def main():
# 創(chuàng)建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 綁定端口和ip
tcp_server_socket.bind(("", 8081))
# 設置套接字為被動監(jiān)聽模式,不能主動發(fā)送數(shù)據(jù),128為允許接收的最大連接數(shù)
tcp_server_socket.listen(128)
while True:
# 接收客戶端連接
new_client_socket, client_ip_port = tcp_server_socket.accept()
t1 = Thread(target=new_client_connect, args=(new_client_socket, client_ip_port))
t1.start()
# tcp_server_socket.close() # 表示不再接受新客戶端的連接,已經(jīng)連接的可以繼續(xù)服務
if __name__ == '__main__':
main()
?效果:文章來源:http://www.zghlxwxcb.cn/news/detail-409054.html
python TCPSocket服務器 (多線程實現(xiàn)消息的接收功能)文章來源地址http://www.zghlxwxcb.cn/news/detail-409054.html
到了這里,關(guān)于使用 python socket 實現(xiàn)UDP/TCP網(wǎng)絡通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!