在windows环境主机A上想每隔15分钟获取远程Linux主机B上定时监控的logFile文件,但经过在A主机上:telnet B'ip port
(例:telnet 158.123.12.1 21)
查看远程主机没开放21
、22
端口,好像不能使用ftp
或者sftp
来获取(应该是不能够吧)。想本身写个简单服务器实现:
一、服务器端可以正确读取logFile内容
二、客户端访问时,服务器端可以返回logFile的内容
二、客户端可以正确获取logFile内容并写入本地文件中python
使用Python的socket
模块,本身新增一个能够直接访问的PORT。为了保证数据准确性,使用比较简单的方法:客户端与服务器端经过TCP方式通讯。服务器端先启动后,循环等待客户端访问。因为是单个客户端每隔15分钟访问,每完成一次访问便断开链接,因此采用了单线程阻塞的方法实现的服务器端:编程
#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
类型,要选取不冲突的PORT
,在Linux上能够经过netstat -anp | grep PORT'id
例:netstat -anp | grep 8083
,查看端口号占用状况。socket(AF_INET, SOCK_STREAM)
:使用HOST+PORT
时,要使用AF_INET
网络协议搜索主机(也可使用 TCP 和本地[非网络的 AF_LOCAL/AF_UNIX]套接字,可是很明显此时并无使用 IP);使用TCP方式时,要使用SOCK_STREAM
基于流套接字(建立 UDP 套接字,必须使用SOCK_DGRAM
做为套接字类型)。bind(ADDR)
:将地址(主机名、端口号对)绑定到套接字上listen(5)
:设置并启动TCP监听器,参数5
是在链接被转接或拒绝以前,传入链接请求的最大数链接队列最大值。若是Client端请求超过5个,Linux中Server会延迟到链接数低于5时响应链接。未测试过,具体处理流程能够参考:TCP握手与socket通讯细节。因为当前只有一个Client客户端,因此5足够使用。def logFileRead(logFile)
:读取文件的functionaccept()
:被动接受TCP客户端链接,持续等待直到链接到达(阻塞等待)tcpCliSock.recv(BUFSIZE)
:接收TCP消息,BUFSIZE
定义的为缓冲区大小。接收的是Client端传送过来的消息。tcpCliSock.send('%s' % fileContent)
:发送TCP消息,将结果返回给Client段tcpCliSock.close()
:关闭客户端链接tcpSerSock.close()
:退出服务器端#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)
:覆盖写入文件,注意若是该文件不存在会报错tcpCliSock.send(data)
:发送消息给服务器端tcpCliSock.recv(BUFSIZE)
:注意接收服务器端返回消息时,有可能超过BUFSIZE或者超过了MTU等限制,单次获取的记录不完整。因此使用TCP协议时,经过循环判断是否存在待接收消息,直到无消息时才断开链接Python核心编程(第3版)
TCP握手与socket通讯细节
Python中使用socket发送HTTP请求数据接收不完整问题解决方法windows