天天看點

python3 中socket的簡單使用使用工具:

使用工具:

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函數關閉檔案

繼續閱讀