日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

Python 簡單的socket編程(TCP)

系統(tǒng) 2109 0
  • 問題描述

個人認為,Socket編程是一個很重要的東西,無論是什么語言,用到Socket編程的一定有很多,所以,學習Socket編程是很重要的。個人學習Socket編程的原因,是因為自己覺得學Python有一段時間了,想要做個桌面應用程序出來,首先要搞定Socket編程,所以就開始學習了。下面介紹一下簡單的Socket編程。

?

  • 解決方法

直接上代碼,分為兩個程序,一個是服務端的程序,用于接收其他的tcp連接,另一個是客戶端的程序,用于請求連接。

首先,是服務端的程序:

            
              import socket

HOST = '0.0.0.0'  
PORT = 8000

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen()
    while True:
        conn, addr = s.accept()
        print('Connected by', addr)
        while True:
            data = conn.recv(1024)
            if not data:
                break
            conn.sendall(data)
            print('get data ', data.decode('utf-8'))

            
          

這里host寫的是0.0.0.0,指的是允許所有的IP進行tcp連接,如果設置為127.0.0.1,則就是本機訪問,除了服務器程序運行以外的機器無法進行訪問。

port就是指端口,指定tcp通過哪個端口進行連接

接下來就是生成socket對象,這里需要說明的是,有的程序生成socket對象使用的是?

            
              sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            
          

這個和上面代碼中的?

            
              with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            
          

?效果是一樣的,問題在于,使用第一個代碼時,我們進行完連接以后,需要手動的進行close。

            
              sock.close()
            
          

?而如果使用with語句,那么我們就不需要自己手動設置close,程序能夠幫助我們自動關閉,如果你能理解文件操作里面的open 和 with open,那么我相信你也能理解這里with的意思。

socket.AF_INET 指通過ipv4連接,socket.SOCK_STREAM 指通過tcp連接

s.bind 指將套接字綁定到我們之前指定的地址

s.listen 指開始進行監(jiān)聽tcp連接

接下來進行死循環(huán)

conn, addr = s.accept()? ? ? ?接受TCP鏈接并返回(conn, address),其中conn是新的套接字對象,可以用來接收和發(fā)送數據,address是連接客戶端的地址。

接下來再次進行死循環(huán),上一次的死循環(huán),能夠讓我們建立連接以后,發(fā)送多次消息,而這一次的死循環(huán),是循環(huán)接收數據,因為我們接收數據是

            
              data = conn.recv(1024)
            
          

即接收1024字節(jié),所以,如果我們發(fā)送的字節(jié)超過了1024字節(jié),那么我們就進行下一次循環(huán),繼續(xù)接收1024字節(jié),就一直死循環(huán),直到所有的字節(jié)接受完,然后就 break 退出

conn.sendall(data) 指返回數據給客戶端,sendall指一次性發(fā)送所有的數據,因為如果我們要發(fā)送的數據超過了1024字節(jié),用send方法發(fā)送數據的話,一次性是發(fā)送不完的,是需要用死循環(huán)進行發(fā)送的, 但是如果我們用sendall,就不用死循環(huán)發(fā)送了。需要注意的是,我們收到或者發(fā)送的數據是bytes格式的,所以我們在發(fā)送數據時,需要用encode,將接收的數據變成字符串時,我們需要用decode。

?

接下來是客戶端程序

            
              import socket

HOST = '192.168.5.135'  # 服務器的主機名或者 IP 地址
PORT = 8000        # 服務器使用的端口

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.settimeout(5)
    while True:
        try:
            a = input('please input:')
            s.sendall(a.encode('utf-8'))
            data = s.recv(1024)
            print('Received', data.decode('utf-8'))
        except socket.timeout as e:
            print('time out')
            continue
            
          

?host指服務器ip

port指服務器端口

使用with 語句創(chuàng)建socket對象

s.connect進行tcp連接

s.settimeout(5)設置超時時間,如果一段5秒以后沒有還是沒有和服務器進行正常的通信,那么,就拋出socket.timeout異常

接下來進行死循環(huán),我們使用input發(fā)送我們想發(fā)送的字符串

然后使用sendall進行發(fā)送,發(fā)送之前使用encode將字符串轉為bytes格式

接下來進行recv,接收服務器返回來的數據

打印輸入服務器數據

如果我們捕獲了socket.timeout異常,則進行下一次的數據發(fā)送

下圖為客戶端程序輸出:

下圖為服務端程序輸出:

至此,簡單的tcp程序就完成了

?

  • 總結

有了上面的程序,再進行一點異常的捕獲、優(yōu)化,我們就能夠進行相對穩(wěn)定的tcp連接了, 如果后面有碰到多連接的情況,再進行處理。


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 陆河县| 拉萨市| 汉川市| 临江市| 大同市| 济阳县| 县级市| 交城县| 河曲县| 衡水市| 达孜县| 沈阳市| 孟连| 蓝田县| 博罗县| 桐柏县| 昭通市| 淮北市| 贺兰县| 兰州市| 安达市| 惠州市| 水城县| 金昌市| 瓮安县| 三江| 芮城县| 永吉县| 仪征市| 漳浦县| 樟树市| 海宁市| 南和县| 泽库县| 乃东县| 乐清市| 县级市| 屯留县| 普兰县| 天镇县| 祁门县|