使用工具:
Ubuntu:vim
Ubuntu:Python 3.7
網絡調試助手 netassist 3.7(windows版本)
前言:網絡程式設計實作計算機之間的通信,通過 指定的協定實作資料的發送與接收,進而達到計算機之間的通信。
TCP/UDP協定,計算機實作通信要遵守的規則:
UDP協定簡單但是不穩定,容易出現丢包的情況,而TCP相比UDP而言,比較複雜,穩定且資料不容易丢失。
以下代碼在Python3.7環境實作。
UDP的使用:
使用UDP向指定網絡位置發送資料:
import socket #導入包
def main():#定義函數
#1.建立一個套接字
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#2向指定網絡位置發送資料(b表示将資料轉換為二進制,("192.168.188.1",8000)是個元組,表示資料的目的地IP及port)
udp_socket.sendto(b"haahahah",("192.168.188.1",8000))
#3關閉套接字
udp_socket.close()
#需要特别注意主函數的寫法
if __name__=="__main__":
main()
手動輸入即将發送的消息:
import socket
def main():
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
contents=input("input message")
#将需要發送的資料進行編碼處理
udp_socket.sendto(contents.encode("UTF-8"),("192.168.188.1",8000))
udp_socket.close()
if __name__=="__main__":
main()
實作循環發送消息:
import socket
def main():
#可以使用Ctrl+c強制結束
while True:
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
contents=input("input message")
udp_socket.sendto(contents.encode("UTF-8"),("192.168.188.1",8000))
udp_socket.close()
if __name__=="__main__":
main()
帶有退出的循環發送:
import socket
def main():
while True:
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
contents=input("input message")
#輸入exit觸發if條件退出循環
if contents == "exit":
break
udp_socket.sendto(contents.encode("UTF-8"),("192.168.188.1",8000))
udp_socket.close()
if __name__=="__main__":
main()
接收資訊:
import socket
def main():
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#定義一個位址元組
localaddr = ('',2000)
#作為伺服器一端綁定自己 的位置
udp_socket.bind(localaddr)
#使用套接字進行資料的接收,1024表示接收資料的大小
recv_date=udp_socket.recvfrom(1024)
#列印接受到的資料
print(recv_date)
udp_socket.close()
if __name__== "__main__":
main()
實作一個簡單聊天室的案例:
import socket
def send_msg(udp_socket):
dest_ip = input("ip:")
dest_port = int(input("port:"))
msg = input("msg:")
udp_socket.sendto(msg.encode("utf-8"),(dest_ip,dest_port))
def recv_msg(udp_socket):
recv_data = udp_socket.recvfrom(1024)
#标準格式輸出
print("%s:%s" %(str(recv_data[1]),recv_data[0].decode("utf-8")))
def main():
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
udp_socket.bind(("",5000))
while True:
#選項操作
print("___choose___")
print("1 to send")
print("2 to resv")
print("3 to exit")
op = input("please input:")
if op == "1":
send_msg(udp_socket)
elif op == "2":
recv_msg(udp_socket)
elif op == "3":
break
else:
print("error!")
if __name__=="__main__":
main()
TCP的使用:
向指定伺服器發送資料
import socket
def main():
#建立套接字
tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#輸入伺服器ip位址及port
server_ip = input("server IP:")
server_port =int( input("server port:"))
#連接配接指定伺服器
tcp_socket.connect((server_ip,server_port))
#輸入即将發送的消息
msg = input("msg:")
#對發送的 消息進行編碼處理
tcp_socket.send(msg.encode("gbk"))
#關閉套接字
tcp_socket.close
if __name__=="__main__":
main()
TCP的伺服器
import socket
def main():
tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
address = ("",5000)
#服務綁定一個ip及port
tcp_socket.bind(address)
#将套接字變為被動狀态(監聽)
tcp_socket.listen(128)
while True:
print("waiting....")
#拆包得到一個新的套接字及一個用戶端的位址
new_socket, new_addr = tcp_socket.accept()
print("new client%s" %str(new_addr))
while True:
new_msg = new_socket.recv("1024")
#對接收到的資訊進行解碼輸出
print("msg%s" %new_msg.decode("utf-8"))
if new_msg:
#伺服器回送消息進行編碼
new_msg.send("hahah...".encode("utf-8"))
else:
break
new_socket.close()
print("over...")
tcp_socket.close()
if __name__=="__main__":
main()
使用TCP下載下傳檔案:
用戶端發送請求及接收資料簡單版
import socket
def main():
tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
dest_ip = input("input_server_ip:")
dest_port = int(input("input_server_port:"))
#連接配接到伺服器
tcp_socket.connect((dest_ip,dest_port))
download_file_name = input("input file name:")
#向伺服器發送下載下傳檔案的請求
tcp_socket.send(download_file_name.encode("utf-8"))
#接收伺服器發送過來的資料
recv_data = tcp_socket.recv(1024)
if recv_data:
with open("[new]"+download_file_name,"wb") as f:
f.write(recv_data)
tcp_socket.close()
if __name__=="__main__":
main()
伺服器端的代碼:
import socket
def send_2_client(new_socket,new_addr):
file_name = new_socket.recv(1024).decode("utf-8")
#the client want to download the file(用戶端請求下載下傳的檔案名稱)
print("the client(%s) want to download the file which name is %s" %(str(new_addr),file_name))
#将讀出檔案内容置為空
file_content = None
#加上異常處理語句,防止檔案打不開出現異常
try:
#rb表示讀檔案用二進制讀出并發送,這時要注意異常處理,wb可以使用with用法,不用考慮檔案打不開的情況
f = open(file_name,"rb")
#讀檔案到file_content
file_content = f.read()
f.close()
except Exception as ret:
print("there is no file which name is %s" % file_name)
#如果檔案讀出内容則執行發送指令
if file_content:
new_socket.send(file_content)
def main():
tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp_socket.bind(("",7788))
tcp_socket.listen(128)
while True:
new_socket,new_addr = tcp_socket.accept()
#調用函數
send_2_client(new_socket,new_addr)
new_socket.close()
tcp_socket.close()
if __name__=="__main__":
main()
with打開檔案的用法:
with open("[new]"+download_file_name,"wb") as f:
f.write(recv_data)
使用with打開檔案時會自動調用close函數關閉檔案