摘要:服務(wù)器端先啟動(dòng)后,循環(huán)等待客戶端訪問(wèn)。使用時(shí),要使用網(wǎng)絡(luò)協(xié)議搜索主機(jī)也可以使用和本地非網(wǎng)絡(luò)的套接字,但是很明顯此時(shí)并沒(méi)有使用使用方式時(shí),要使用基于流套接字創(chuàng)建套接字,必須使用作為套接字類(lèi)型。
問(wèn)題
在windows環(huán)境主機(jī)A上想每隔15分鐘獲取遠(yuǎn)程Linux主機(jī)B上定時(shí)監(jiān)控的logFile文件,但通過(guò)在A主機(jī)上:telnet B"ip port (例:telnet 158.123.12.1 21)查看遠(yuǎn)程主機(jī)沒(méi)開(kāi)放21、22端口,好像不能使用ftp或者sftp來(lái)獲取(應(yīng)該是不可以吧)。想自己寫(xiě)個(gè)簡(jiǎn)單服務(wù)器實(shí)現(xiàn):
1、服務(wù)器端能夠正確讀取logFile內(nèi)容
2、客戶端訪問(wèn)時(shí),服務(wù)器端能夠返回logFile的內(nèi)容
2、客戶端能夠正確獲取logFile內(nèi)容并寫(xiě)入本地文件中
使用Python的socket模塊,自己新增一個(gè)可以直接訪問(wèn)的PORT。為了保證數(shù)據(jù)準(zhǔn)確性,使用比較簡(jiǎn)單的方法:客戶端與服務(wù)器端通過(guò)TCP方式通信。服務(wù)器端先啟動(dòng)后,循環(huán)等待客戶端訪問(wèn)。由于是單個(gè)客戶端每隔15分鐘訪問(wèn),每完成一次訪問(wèn)便斷開(kāi)連接,所以采用了單線程阻塞的方法實(shí)現(xiàn)的服務(wù)器端:
#coding=utf-8 #!/usr/bin/python from socket import * HOST = "158.123.12.1" PORT = 8083 BUFSIZE = 65535 ADDR = (HOST, PORT) tcpSerSock = socket(AF_INET, SOCK_STREAM) tcpSerSock.bind(ADDR) tcpSerSock.listen(5) welcomeStr = "Welcome to 12.1 python socket server" def logFileRead(logFile): """ Read logFile by line return List """ logFileDealList = [] with open(logFile, "r") as logFileContent: for line in logFileContent.readlines(): logFileDealList.append(line) return logFileDealList if __name__ == "__main__": fileDir = "filePath/warningMessage.txt" while True: print "Enter 12.1 python socket server" tcpCliSock, addr = tcpSerSock.accept() print "Connected from : ", addr data = tcpCliSock.recv(BUFSIZE) if not data: break print data logFileContentList = logFileRead(fileDir) # print logFileContentList for fileContent in logFileContentList: if fileContent.find("pending") == -1: continue tcpCliSock.send("%s" % fileContent) tcpCliSock.close() tcpSerSock.close()
ADDR 中PORT為int類(lèi)型,要選取不沖突的PORT,在Linux上可以通過(guò)netstat -anp | grep PORT"id 例:netstat -anp | grep 8083,查看端口號(hào)占用情況。
socket(AF_INET, SOCK_STREAM):使用HOST+PORT時(shí),要使用AF_INET網(wǎng)絡(luò)協(xié)議搜索主機(jī)(也可以使用 TCP 和本地[非網(wǎng)絡(luò)的 AF_LOCAL/AF_UNIX]套接字,但是很明顯此時(shí)并沒(méi)有使用 IP);使用TCP方式時(shí),要使用SOCK_STREAM基于流套接字(創(chuàng)建 UDP 套接字,必須使用SOCK_DGRAM作為套接字類(lèi)型)。
bind(ADDR):將地址(主機(jī)名、端口號(hào)對(duì))綁定到套接字上
listen(5):設(shè)置并啟動(dòng)TCP監(jiān)聽(tīng)器,參數(shù)5是在連接被轉(zhuǎn)接或拒絕之前,傳入連接請(qǐng)求的最大數(shù)連接隊(duì)列最大值。如果Client端請(qǐng)求超過(guò)5個(gè),Linux中Server會(huì)延遲到連接數(shù)低于5時(shí)響應(yīng)連接。未測(cè)試過(guò),具體處理流程可以參考:TCP握手與socket通信細(xì)節(jié)。由于當(dāng)前只有一個(gè)Client客戶端,所以5足夠使用。
def logFileRead(logFile):讀取文件的function
accept():被動(dòng)接受TCP客戶端連接,持續(xù)等待直到連接到達(dá)(阻塞等待)
tcpCliSock.recv(BUFSIZE):接收TCP消息,BUFSIZE定義的為緩沖區(qū)大小。接收的是Client端傳送過(guò)來(lái)的消息。
tcpCliSock.send("%s" % fileContent):發(fā)送TCP消息,將結(jié)果返回給Client段
tcpCliSock.close():關(guān)閉客戶端連接
tcpSerSock.close():退出服務(wù)器端
執(zhí)行時(shí),可以將Server端掛載到后臺(tái)不退出
#coding=utf-8 #!/usr/bin/python from socket import * HOST = "158.123.12.1" PORT = 8083 BUFSIZE = 65535 ADDR = (HOST, PORT) welcomeStr = "Welcome to 12.1 python socket server" def fileWrite(record, fileName): with open(fileName, "w") as logFile: for recordItem in record: logFile.write(recordItem) def main(): tcpCliSock = socket(AF_INET, SOCK_STREAM) tcpCliSock.connect(ADDR) fileDir = "filePath/warnLogFile.txt" print "Will connect 12.1 python socket server" data = "hello" tcpCliSock.send(data) retDataAll = "" while True: retDataTmp = tcpCliSock.recv(BUFSIZE) if not retDataTmp: break if not len(retDataTmp): break print retDataTmp retDataAll = retDataAll + retDataTmp print "end " tcpCliSock.close() fileWrite(retDataAll, fileDir) if __name__ == "__main__": main()
ADDR = (HOST, PORT):與Server端HOST、PROT相同
def fileWrite(record, fileName):覆蓋寫(xiě)入文件,注意如果該文件不存在會(huì)報(bào)錯(cuò)
tcpCliSock.send(data):發(fā)送消息給服務(wù)器端
tcpCliSock.recv(BUFSIZE):注意接收服務(wù)器端返回消息時(shí),有可能超過(guò)BUFSIZE或者超過(guò)了MTU等限制,單次獲取的記錄不完整。所以使用TCP協(xié)議時(shí),通過(guò)循環(huán)判斷是否存在待接收消息,直到無(wú)消息時(shí)才斷開(kāi)連接
參考文章Python核心編程(第3版)
TCP握手與socket通信細(xì)節(jié)
Python中使用socket發(fā)送HTTP請(qǐng)求數(shù)據(jù)接收不完整問(wèn)題解決方法
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/40924.html
摘要:套接字有兩種或者稱為有兩個(gè)種族分別是基于文件型的和基于網(wǎng)絡(luò)型的。大部分網(wǎng)絡(luò)設(shè)備的都是。不會(huì)發(fā)生黏包,用戶數(shù)據(jù)報(bào)協(xié)議是無(wú)連接的,面向消息的,提供高效率服務(wù)。即面向消息的通信是有消息保護(hù)邊界的。 軟件開(kāi)發(fā)的架構(gòu) 我們了解的涉及到兩個(gè)程序之間通訊的應(yīng)用大致可以分為兩種: 第一種是應(yīng)用類(lèi):qq、微信、網(wǎng)盤(pán)、優(yōu)酷這一類(lèi)是屬于需要安裝的桌面應(yīng)用 第二種是web類(lèi):比如百度、知乎、博客園等使用瀏覽器...
摘要:在任何類(lèi)型的通信開(kāi)始之前,網(wǎng)絡(luò)應(yīng)用程序必須創(chuàng)建套接字?;谖募奶捉幼郑易迕置诰W(wǎng)絡(luò)的套接字,家族名在和后續(xù)的版本中,支持的套接字有,,,。中的網(wǎng)絡(luò)編程在中主要是用模塊來(lái)實(shí)現(xiàn)基于套接字的網(wǎng)絡(luò)通信。 python學(xué)習(xí)記錄--網(wǎng)絡(luò)編程 1、套接字介紹 一臺(tái)機(jī)器上的不同進(jìn)程之間進(jìn)行通信可以利用隊(duì)列,管道等,但是不同機(jī)器之間的進(jìn)程進(jìn)行通信用隊(duì)列是不行的,解決這個(gè)問(wèn)題就是網(wǎng)絡(luò)套接字。 套接...
摘要:當(dāng)一個(gè)客戶端連接時(shí),它將返回一個(gè)新的對(duì)象,對(duì)象中有表示當(dāng)前連接的和一個(gè)由主機(jī)端口號(hào)組成的連接的元組,更多關(guān)于元組值的內(nèi)容可以查看地址族一節(jié)中的詳情這里必須要明白我們通過(guò)調(diào)用方法擁有了一個(gè)新的對(duì)象。 博客原文: https://keelii.com/2018/09/24/socket-programming-in-python/ 說(shuō)明 本書(shū)翻譯自 realpython 網(wǎng)站上的文章教程 ...
閱讀 991·2021-11-23 09:51
閱讀 2705·2021-08-23 09:44
閱讀 667·2019-08-30 15:54
閱讀 1440·2019-08-30 13:53
閱讀 3115·2019-08-29 16:54
閱讀 2533·2019-08-29 16:26
閱讀 1200·2019-08-29 13:04
閱讀 2327·2019-08-26 13:50