python利用socket實(shí)現(xiàn)客戶(hù)端和服務(wù)端之間進(jìn)行通信
前言:
今天教大家通過(guò)Python進(jìn)行Socket網(wǎng)絡(luò)編程(做一個(gè)聊天程序),可以實(shí)現(xiàn)在不同的主機(jī)(電腦)之間進(jìn)行通話。
具體效果如何,接著往下看:
可以看到客戶(hù)端(上方)向服務(wù)器端(下方)發(fā)送了內(nèi)容,服務(wù)器端進(jìn)行了回復(fù)
【備注:客戶(hù)端是我的本機(jī),服務(wù)器是另一條主機(jī)(阿里云服務(wù)器)】
兩臺(tái)主機(jī)的目的:驗(yàn)證兩臺(tái)主機(jī)可以相互通信
一、socket
先簡(jiǎn)單給大家介紹一下什么是socket,socket(簡(jiǎn)稱(chēng) 套接字) 是進(jìn)程間通信的一種方式,它與其他進(jìn)程間通信的一個(gè)主要不同是:它能實(shí)現(xiàn)不同主機(jī)間的進(jìn)程間通信。
我們網(wǎng)絡(luò)上各種各樣的服務(wù)大多都是基于 Socket 來(lái)完成通信的,例如瀏覽網(wǎng)頁(yè)、QQ 聊天、收發(fā) email 等等
簡(jiǎn)單的說(shuō):socket可以實(shí)現(xiàn)不同主機(jī)間進(jìn)行通信
socket通信的條件:IP和端口
ip相信大家都陌生了,每一臺(tái)主機(jī)都有一個(gè)ip,不同主機(jī)之間通信的首要前提就是ip可以互訪,此外還有一個(gè)條件就是端口,比如我們經(jīng)常聽(tīng)到的80端口,3306端口,8080端口等。
主機(jī)中的數(shù)據(jù)是通過(guò)端口發(fā)送和接收,需要將對(duì)應(yīng)端口打開(kāi)才能進(jìn)行通信。
形象比喻
ip相當(dāng)于家庭地址,端口相當(dāng)于門(mén)或者窗戶(hù)
例子:
(主機(jī)A)快遞員要想將快遞(數(shù)據(jù))送到你手中(另一臺(tái)主機(jī)B),需要知道你家的地址(主機(jī)B的ip),到你家門(mén)口后,需要你打開(kāi)門(mén)(主機(jī)B的端口)才能拿到快遞(數(shù)據(jù))。
這里需要分服務(wù)端和客戶(hù)端,客戶(hù)端發(fā)送(主機(jī)A),服務(wù)器接收(主機(jī)B),當(dāng)然了,每一臺(tái)主機(jī)可以充當(dāng)兩個(gè)角色(既是客戶(hù)端,也是服務(wù)器),這樣就可以實(shí)現(xiàn)兩臺(tái)主機(jī)之間相互發(fā)送和接收。
看到這里之后,相信大家都清楚socket在實(shí)現(xiàn)不同主機(jī)之間通信的大概意思了,下面開(kāi)始Python代碼實(shí)現(xiàn)。
二、客戶(hù)端實(shí)現(xiàn)過(guò)程
先來(lái)分析客戶(hù)端(主機(jī)A)的實(shí)現(xiàn)過(guò)程:
from socket import * # 1.創(chuàng)建套接字 tcp_socket = socket(AF_INET,SOCK_STREAM) # 2.準(zhǔn)備連接服務(wù)器,建立連接 serve_ip = "服務(wù)器端(主機(jī)B)的IP" serve_port = 8000 #端口,比如8000 tcp_socket.connect((serve_ip,serve_port)) # 連接服務(wù)器,建立連接,參數(shù)是元組形式
首先與服務(wù)器接收端(主機(jī)B)建立連接,連接條件(主機(jī)B的ip和端口),這里的端口8000是指將數(shù)據(jù)發(fā)送到主機(jī)B的端口(主機(jī)B到時(shí)候會(huì)監(jiān)聽(tīng)8000端口,然后進(jìn)行接收數(shù)據(jù))
#準(zhǔn)備需要傳送的數(shù)據(jù) send_data = "今天是2021年08月29日,辰哥給服務(wù)器端發(fā)送數(shù)據(jù)了" tcp_socket.send(send_data.encode("gbk")) #從服務(wù)器接收數(shù)據(jù) #注意這個(gè)1024byte,大小根據(jù)需求自己設(shè)置 from_server_msg = tcp_socket.recv(1024) #加上.decode("gbk")可以解決亂碼 print(from_server_msg.decode("gbk")) #關(guān)閉連接 tcp_socket.close()
send_data是往服務(wù)器端(主機(jī)B)發(fā)送的內(nèi)容,from_server_msg是服務(wù)器端(主機(jī)B)往客戶(hù)端(主機(jī)A)發(fā)送的內(nèi)容
客戶(hù)端的代碼就結(jié)束了
三、服務(wù)器實(shí)現(xiàn)過(guò)程
分析服務(wù)器端(主機(jī)B)的實(shí)現(xiàn)過(guò)程:
from socket import * #創(chuàng)建套接字 tcp_server = socket(AF_INET,SOCK_STREAM) #綁定ip,port #這里ip默認(rèn)本機(jī) address = ('',8000) tcp_server.bind(address) # 啟動(dòng)被動(dòng)連接 #多少個(gè)客戶(hù)端可以連接 tcp_server.listen(128) #使用socket創(chuàng)建的套接字默認(rèn)的屬性是主動(dòng)的 #使用listen將其變?yōu)楸粍?dòng)的,這樣就可以接收別人的鏈接了
服務(wù)器端(主機(jī)B)ip可以留空(默認(rèn)本機(jī)),端口8000(因?yàn)榭蛻?hù)端往8000端口發(fā)送數(shù)據(jù),所以服務(wù)器需要監(jiān)聽(tīng)的端口也是8000,與客戶(hù)端的端口一致)
# 創(chuàng)建接收 # 如果有新的客戶(hù)端來(lái)鏈接服務(wù)器,那么就產(chǎn)生一個(gè)新的套接字專(zhuān)門(mén)為這個(gè)客戶(hù)端服務(wù) client_socket, clientAddr = tcp_server.accept()
client_socket用來(lái)為這個(gè)客戶(hù)端服務(wù),相當(dāng)于的tcp_server套接字的代理 tcp_server_socket就可以省下來(lái)專(zhuān)門(mén)等待其他新客戶(hù)端的鏈接 這里clientAddr存放的就是連接服務(wù)器的客戶(hù)端地址 #接收對(duì)方發(fā)送過(guò)來(lái)的數(shù)據(jù) from_client_msg = client_socket.recv(1024)#接收1024給字節(jié),這里recv接收的不再是元組,區(qū)別UDP print("接收的數(shù)據(jù):",from_client_msg.encode("gbk")) #發(fā)送數(shù)據(jù)給客戶(hù)端 send_data = client_socket.send("客戶(hù)端你好,服務(wù)器端收到,公眾號(hào)【Python研究者】".encode("gbk")) #關(guān)閉套接字 #關(guān)閉為這個(gè)客戶(hù)端服務(wù)的套接字,就意味著為不能再為這個(gè)客戶(hù)端服務(wù)了 #如果還需要服務(wù),只能再次重新連 client_socket.close()
from_client_msgs 是服務(wù)器端(主機(jī)B)接收到來(lái)自客戶(hù)端(主機(jī)A)發(fā)送過(guò)來(lái)的數(shù)據(jù)send_data 是服務(wù)器端(主機(jī)B)往客戶(hù)端(主機(jī)A)發(fā)送過(guò)去的數(shù)據(jù)
服務(wù)器端的代碼就結(jié)束了
提醒:服務(wù)器端的8000端口需要開(kāi)啟,不然無(wú)法進(jìn)行通信
四、演示
先啟動(dòng)(執(zhí)行)服務(wù)器端(主機(jī)B)的程序,再執(zhí)行客戶(hù)端(主機(jī)A)
可以看到客戶(hù)端(上方)向服務(wù)器端(下方)發(fā)送了內(nèi)容,服務(wù)器端進(jìn)行了回復(fù)
發(fā)送和響應(yīng)內(nèi)容:
客戶(hù)端發(fā)送:今天是2021年08月29日,辰哥給服務(wù)器端發(fā)送數(shù)據(jù)了
服務(wù)器端接收并回復(fù)給客戶(hù)端:客戶(hù)端你好,服務(wù)器端收到,公眾號(hào)【Python研究者】
五、實(shí)現(xiàn)持續(xù)通信過(guò)程
上方動(dòng)圖演示的是客戶(hù)端和服務(wù)端的一次通信過(guò)程,可以將客戶(hù)端的發(fā)送和服務(wù)端的接收放到循環(huán)中,實(shí)現(xiàn)持續(xù)通信過(guò)程。
客戶(hù)端:
while(1): send_data = input("請(qǐng)輸入內(nèi)容:") #send_data = "今天是2021年08月29日,辰哥給服務(wù)器端發(fā)送數(shù)據(jù)了" tcp_socket.send(send_data.encode("gbk")) if send_data == "exit": break; #從服務(wù)器接收數(shù)據(jù) #注意這個(gè)1024byte,大小根據(jù)需求自己設(shè)置 from_server_msg = tcp_socket.recv(1024) #加上.decode("gbk")可以解決亂碼 print(from_server_msg.decode("gbk")) #關(guān)閉連接 tcp_socket.close()
服務(wù)端:
while(1): #接收對(duì)方發(fā)送過(guò)來(lái)的數(shù)據(jù) from_client_msg = client_socket.recv(1024)#接收1024給字節(jié),這里recv接收的不再是元組,區(qū)別UDP if(from_client_msg=="exit"): break print("接收的數(shù)據(jù):",from_client_msg.decode("gbk")) now_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) #發(fā)送數(shù)據(jù)給客戶(hù)端 send_data = client_socket.send((str(now_time)+" 服務(wù)端:客戶(hù)端你好,服務(wù)器端收到,公眾號(hào)【Python研究者】").encode("gbk")) #關(guān)閉套接字 #關(guān)閉為這個(gè)客戶(hù)端服務(wù)的套接字,就意味著為不能再為這個(gè)客戶(hù)端服務(wù)了 #如果還需要服務(wù),只能再次重新連 client_socket.close()
客戶(hù)端可以持續(xù)給服務(wù)端發(fā)送數(shù)據(jù),服務(wù)器接收數(shù)據(jù)后打印并返回?cái)?shù)據(jù)給客戶(hù)端
服務(wù)端返回的內(nèi)容:
當(dāng)前系統(tǒng)時(shí)間+服務(wù)端:客戶(hù)端你好,服務(wù)器端收到
最后當(dāng)客戶(hù)端輸入:exit,則斷開(kāi)與服務(wù)端的連接:
到此這篇關(guān)于python利用socket實(shí)現(xiàn)客戶(hù)端和服務(wù)端之間進(jìn)行通信 的文章就介紹到這了,更多相關(guān)python主機(jī)通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python實(shí)現(xiàn)帶聲音的摩斯碼翻譯實(shí)現(xiàn)方法
這篇文章主要介紹了python實(shí)現(xiàn)帶聲音的摩斯碼翻譯實(shí)現(xiàn)方法,涉及pygame模塊操作及摩斯碼實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-05-05Python搭建自己IP代理池的方法實(shí)現(xiàn)
本文主要介紹了Python搭建自己IP代理池的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02淺談cv2.imread()和keras.preprocessing中的image.load_img()區(qū)別
這篇文章主要介紹了淺談cv2.imread()和keras.preprocessing中的image.load_img()區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06Python functools.lru_cache裝飾器性能提升利器深入探究
本文將詳細(xì)介紹functools.lru_cache裝飾器的原理、用法以及適當(dāng)?shù)膱?chǎng)景,以幫助你更好地利用這一功能,它可以用來(lái)緩存函數(shù)的輸出,以避免重復(fù)計(jì)算,從而顯著提高程序的執(zhí)行速度2024-01-01PyTorch實(shí)現(xiàn)線性回歸詳細(xì)過(guò)程
本文介紹PyTorch實(shí)現(xiàn)線性回歸,線性關(guān)系是一種非常簡(jiǎn)單的變量之間的關(guān)系,因變量和自變量在線性關(guān)系的情況下,可以使用線性回歸算法對(duì)一個(gè)或多個(gè)因變量和自變量間的線性關(guān)系進(jìn)行建模,該模型的系數(shù)可以用最小二乘法進(jìn)行求解,需要的朋友可以參考一下2022-03-03對(duì)python while循環(huán)和雙重循環(huán)的實(shí)例詳解
今天小編就為大家分享一篇對(duì)python while循環(huán)和雙重循環(huán)的實(shí)例詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08Selenium爬取b站主播頭像并以昵稱(chēng)命名保存到本地
這篇文章主要介紹了使用Selenium自動(dòng)化爬取b站主播頭像并以昵稱(chēng)命名保存到本地的方法,代碼簡(jiǎn)單完整,對(duì)于大家練習(xí)Selenium自動(dòng)化有一定的幫助,需要的朋友可以參考下2021-04-04Python實(shí)現(xiàn)的中國(guó)剩余定理算法示例
這篇文章主要介紹了Python實(shí)現(xiàn)的中國(guó)剩余定理算法,結(jié)合實(shí)例形式分析了中國(guó)剩余定理的概念、原理及具體算法實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-08-08