问题。Windows环境的主机A想每隔15分钟获取远程Linux主机B上定时监控的logFile文件,但是在主机A上:telnetB'ip端口(例如:telnet158.123.12.121)查看远程主机没有打开端口21和22。您似乎不能使用ftp或sftp获取它(可能不能)。想自己写一个简单的服务端实现:1.服务端能正确读取logFile内容。2.客户端访问时,服务端可以返回logFile内容。2.客户端可以正确获取logFile内容并写入本地文件。socket模块,增加一个可以直接访问的PORT。为了保证数据的准确性,采用了一种比较简单的方法:客户端和服务端通过TCP进行通信。服务器先启动后,循环等待客户端访问。由于单个client每隔15分钟访问一次,每次访问完成就断开连接,服务器端采用单线程阻塞方式实现:远程linux主机B服务器端代码:#coding=utf-8#!/usr/bin/pythonfromsocketimport*HOST='158.123.12.1'PORT=8083BUFSIZE=65535ADDR=(HOST,PORT)tcpSerSock=socket(AF_INET,SOCK_STREAM)tcpSerSock.bind(ADDR)tcpSerSock.listen(5)welcomeStr='欢迎到12.1pythonsocketserver'deflogFileRead(logFile):'''ReadlogFilebylinereturnList'''logFileDealList=[]withopen(logFile,'r')aslogFileContent:forlineinlogFileContent.readlines():logFileDealList.append(line)returnlogFileDealListif__name__=="__main__":fileDir='filePath/warningMessage.txt'whileTrue:print'Enter12.1pythonsocketserver'tcpCliSock,addr=tcpSerSock.accept()print'连接自:',地址数据=tcpCliSock.recv(BUFSIZE)ifnotdata:breakprintdatalogFileContentList=logFileRead(fileDir)#打印logFileContentListforfileContentinlogFileContentList:iffileContent.find('pending')==-1:continuetcpCliSock.send('%s'%fileContent)tcpCliSock.close()tcpSerSock.close()ADDR中的PORT是int类型,要选择不冲突的PORT,可以使用netstat-anp|Linux上的grepPORT'id示例:netstat-anp|grep8083查看端口号占用socket(AF_INET,SOCK_STREAM):当使用HOST+PORT时,使用AF_INET网络协议搜索主机(也可以使用TCP和本地[非网络AF_LOCAL/AF_UNIX]sockets,但是显然此时没有使用IP);使用TCP模式时,使用基于SOCK_STREAM的流套接字(要创建UDP套接字,必须使用SOCK_DGRAM作为套接字类型)。bind(ADDR):将地址(主机名,端口号对)绑定到socketlisten(5):设置并启动TCP监听器,参数5为传入的连接请求,在连接被转移或拒绝前最大连接数队列最大值。如果客户端请求超过5个,Linux中服务器会延迟连接响应,直到连接数低于5个。未测试,具体处理流程可参考:TCP握手和套接字通信详解。由于目前只有一个Client客户端,所以5个就够了。deflogFileRead(logFile):functionaccept()用于读取文件:被动接受TCP客户端连接,并继续等待直到连接到达(阻塞等待)tcpCliSock.recv(BUFSIZE):接收TCP消息,BUFSIZE定义缓冲区大小。Received是客户端发送的消息。tcpCliSock.send('%s'%fileContent):发送TCP报文,返回结果给Client段挂载服务器进入后台,不退出本地Windows主机A客户端代码:#coding=utf-8#!/usr/bin/pythonfromsocketimport*HOST='158.123.12.1'PORT=8083BUFSIZE=65535ADDR=(HOST,PORT)welcomeStr='欢迎使用12.1python套接字服务器'deffileWrite(record,fileName):withopen(fileName,'w')aslogFile:forrecordIteminrecord:logFile.write(recordItem)defmain():tcpCliSock=socket(AF_INET,SOCK_STREAM)tcpCliSock.connect(ADDR)fileDir='filePath/warnLogFile.txt'print'Willconnect12.1pythonsocketserver'data='hello'tcpCliSock.send(data)retDataAll=''whileTrue:retDataTmp=tcpCliSock。recv(BUFSIZE)如果不是retDataTmp:如果不是len(retDataTmp)则中断:breakprintretDataTmpretDataAll=retDataAll+retDataTmpprint'end'tcpCliSock.close()fileWrite(retDataAll,fileDir)if__name__=='__main__':main()ADDR=(HOST,PORT):与服务器端HOST相同,PROTdeffileWrite(record,fileName):覆盖写入文件,注意如果文件不存在会报错tcpCliSock.send(data):向服务器发送消息tcpCliSock.recv(BUFSIZE):注意收到服务器返回的报文时,可能会超过BUFSIZE或超过MTU等限制,单次获取的记录不完整。所以在使用TCP协议时,通过循环判断是否有要接收的消息,直到没有消息才断开连接。参考文章Python核心编程(第3版)TCP握手与socket通信详解Python中使用socket发送HTTP请求Datareceivedincomplete问题解决
