python網絡編程:udp&tcp&socket

socket:套接字,在不一樣主機之間實現通訊。
udp:用戶數據報協議。在通訊開始前不須要創建鏈接,只須要發送數據便可。不安全
tcp:傳輸控制協議,面向鏈接。通訊雙方必須先創建鏈接才能進行數據傳輸,雙方都必須爲鏈接分配系統內核資源,以管理鏈接狀態和傳輸數據;完成傳輸後,雙方必須斷開鏈接,釋放資源。
tcp相似於打電話,udp相似於投遞信件。由於鏈接是1對1的,因此tcp不適用於廣播的應用程序,基於廣播的應用程序使用udp協議。
單工:只支持數據在一個方向上傳輸;在同一時間只有一方能接受或發送信息,不能實現雙向通訊,舉例:電視,廣播
半雙工:容許數據在兩個方向上傳輸,可是,在某一時刻,只容許數據在一個方向上傳輸,它其實是一種切換方向的單工通訊;在同一時間只能夠有一方接受或發送信息,能夠實現雙向通訊。舉例:對講機
全雙工:容許數據同時在兩個方向上傳輸,所以,全雙工通訊是兩個單工通訊方式的結合,它要求發送設備和接收設備都有獨立的接收和發送能力;在同一時間能夠同時接受和發送信息,實現雙向通訊,舉例:電話通訊
(圖片來自網絡,若有侵權請聯繫刪除)

在python網絡編程中,對於udp協議處理流程以下圖:

 

對於tcp協議的處理流程以下圖:html

 

 

根據上方流程引出案例:使用udp實現簡單的網絡通訊python

import socket

def send(udp_socket):
    dest_ip=input("請輸入目標ip地址:")
    dest_port=int(input("請輸入目標端口:"))
    send_date=input("請輸入要發送的數據:")
    udp_socket.sendto(send_date.encode('utf-8'),(dest_ip,dest_port))    #向目標ip:port發送數據

def recv(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)      #新建一個ipv4的udp socket
    udp_socket.bind(("",7788))      #爲socket綁定一個端口

    while True:
        print("---------udp聊天----------")
        print("1:發送消息")
        print("2:接收消息")
        print("0:退出系統")
        op=input("請輸入操做編號:")
        if op == "1":
            send(udp_socket)
        elif op == "2":
            recv(udp_socket)
        elif op == "0":
            break
        else:
            print("輸入錯誤請從新輸入")

if __name__=="__main__":
    main()

同理引出tcp案例:編程

 服務端:安全

import socket
import threading
import time

def main():
    #tcp_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    tcp_service()

def tcp_service():  #服務端socket,接收客戶端鏈接,把客戶端發來的字符串加上hello發送回去
    tcp_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    tcp_sock.bind(('127.0.0.1',9999))
    tcp_sock.listen(5)     #監聽端口,傳參指定等待鏈接的最大數量5
    print("wait for connect...")
    while True:
        sock,addr=tcp_sock.accept()     #創建鏈接
        t=threading.Thread(target=tcplink,args=(sock,addr))     #建立一個新線程去處理鏈接
        t.start

def tcplink(sock,addr):     #爲每一個鏈接創建一個線程
    print("Accept new connection from %s:%s" %addr)
    sock.send(b'Hello')
    while True:
        data=sock.recv(1024)
        time.sleep(1)
        if not data or data.decode('utf-8') == 'exit':
            break
        sock.send(('Hello,%s!' % data.decode('utf-8')).encode('utf-8'))
    sock.close()
    print('Connection from %s:%s closed' %addr)

if __name__=='__main__':
    main()

客戶端:網絡

import socket

def main():
    test_link()

def tcp_client():   #客戶端socket,進行數據的發送與收集
    tcp_c= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_c.connect(('127.0.0.1',9999))
    tcp_c.send(b'GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n')  # 發送請求

    buffer = []
    while (True):
        d = tcp_c.recv(1024)
        if d:
            buffer.append(d)
        else:  # 一直接收數據,一次最多接收1024位字節;當接收數據爲空時,接收完畢,退出循環
            break
    data = b''.join(buffer)
    tcp_c.close()

    header,html=data.split(b'\r\n\r\n',1)   #將http頭和html分離,http頭打印出來,html保存在本地
    print(header.decode('utf-8'))
    with open('test html','wb') as f:
        f.write(html)

def test_link():    #測試鏈接
    tcp_t= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_t.connect(('127.0.0.1',9999))
    print(tcp_t.recv(1024).decode('utf-8'))
    for data in [b'mike',b'bob',b'lili']:
        tcp_t.send(data)
        print(tcp_t.recv(1024).decode('utf-8'))
    tcp_t.send(b'exit')
    tcp_t.close


if __name__=='__main__':
    main()
    
相關文章
相關標籤/搜索