UDP/TCP/AF_UNIX服务器、客户端工具(py)添加了以太网嗅探能力, 添加了websocket服务器功能

小工具包括tcp服务/客户端、udp服务/客户端、AF_UNIX服务/客户端

可以手动修改IP、tcpport以及udpport

获取以太网帧的源IP、目的IP以及TCP头信息


from select import *
import time
import os
import sys
import logging
import re
import binascii

from threading import Thread
import struct
import time
import hashlib
import base64
import socket

#websocket
class returnCrossDomain(Thread):  
    def __init__(self,connection):  
        Thread.__init__(self)  
        self.con = connection  
        self.isHandleShake = False  
    def run(self):  
        while True:  
            if not self.isHandleShake: 
                #开始握手阶段
                header = self.analyzeReq()
                secKey = header['Sec-WebSocket-Key'];  
 
                acceptKey = self.generateAcceptKey(secKey)
 
                response = "HTTP/1.1 101 Switching Protocols\r\n"  
                response += "Upgrade: websocket\r\n"  
                response += "Connection: Upgrade\r\n" 
                response += "Sec-WebSocket-Accept: %s\r\n\r\n"%(acceptKey.decode('utf-8'))  
                self.con.send(response.encode())  
                self.isHandleShake = True  
                print('response:\r\n'+response)
                #握手阶段结束
            else:  
                #接受客户端数据
                opcode = self.getOpcode()  
                if opcode == 8:
                    self.con.close()
                self.getDataLength()
                clientData = self.readClientData()
                print('客户端数据:'+clientData)
                if clientData == 'hello':
                #向客户端发送数据
                    for index in range(len(caseList)):
                        self.sendDataToClient(caseList[index].split('.')[0] )
 
 
    def analyzeReq(self):
        reqData = self.con.recv(1024).decode()
        reqList = reqData.split('\r\n')
        headers = {}
        for reqItem in reqList:
            if ': ' in reqItem:
                unit = reqItem.split(': ')
                headers[unit[0]] = unit[1]
        return headers
 
    def generateAcceptKey(self,secKey):
        sha1 = hashlib.sha1()
        sha1.update((secKey+'258EAFA5-E914-47DA-95CA-C5AB0DC85B11').encode())
        sha1_result = sha1.digest()
        acceptKey = base64.b64encode(sha1_result)
        return acceptKey
 
    def getOpcode(self):
        first8Bit = self.con.recv(1)
        first8Bit = struct.unpack('B',first8Bit)[0]
        opcode = first8Bit & 0b00001111
        return opcode
 
    def getDataLength(self):
        second8Bit = self.con.recv(1)
        second8Bit = struct.unpack('B',second8Bit)[0]
        masking = second8Bit >> 7
        dataLength = second8Bit & 0b01111111
 
        if dataLength <= 125:
            payDataLength = dataLength
        elif dataLength == 126:
            payDataLength = struct.unpack('H',self.con.recv(2))[0]
        elif dataLength == 127:
            payDataLength = struct.unpack('Q',self.con.recv(8))[0]
        self.masking = masking
        self.payDataLength = payDataLength
 
    def readClientData(self):
        if self.masking == 1:
            maskingKey = self.con.recv(4)
 
        data = self.con.recv(self.payDataLength)
 
        if self.masking == 1:
            i = 0
            trueData = ''
            for d in data:
                trueData += chr(d ^ maskingKey[i%4])
                i += 1
            return trueData
        else:
            return data
 
    def sendDataToClient(self,text):
        sendData = ''
        sendData = struct.pack('!B',0x81)
   
        length = len(text)
        if length <= 125:
            sendData += struct.pack('!B',length)
        elif length <= 65536:
            sendData += struct.pack('!B',126)
            sendData += struct.pack('!H',length)
        elif length == 127:
            sendData += struct.pack('!B',127)
            sendData += struct.pack('!Q',length)
 
        sendData += struct.pack('!%ds' % (length),text.encode())
        dataSize = self.con.send(sendData)
 
  
def getIniFile(path):
    iniFileList = []
    dirList = os.listdir(path)
    for file in dirList:
        if file.endswith(".ini") or re.match(r"\w+\.ini", file):
            iniFileList.append(file)
    openFile = open("case.log", "w")

    for file in iniFileList:
        filename = file.split('.')[0] + "\r\n"

        openFile.write(filename)

    return iniFileList


def servermain():  
    print('websocket server start!')
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(('',WEBPORT))  
    sock.listen(5)  
    while True:  
        try:  
            connection,address = sock.accept()  
            returnCrossDomain(connection).start()  
        except:  
            time.sleep(1)  


def tcpServer():

    print("THE TCP SERVER START######################")
    serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    serverAddr_port = (IPADDR, TCPPORT)
    serverSocket.bind(serverAddr_port)

    serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    serverSocket.listen(100)

    inputs = [serverSocket]

    while True:
        readlist, writelist, exceptionlist = select(inputs, [], [])

        for newSocket in readlist:
            if newSocket == serverSocket:
                clientSocket, clientAddr_port = serverSocket.accept()
                print("客户端%s已经连接..."%(str(clientAddr_port)))
                inputs.append(clientSocket)
            else:
                recvData = newSocket.recv(2048)
                if len(recvData) > 0:
                    print("recvData:%s"%(recvData.decode("gb2312")))
                    newSocket.send(b"*-*")
                else:
                    print("客户端已经关闭")

                    inputs.remove(newSocket)
                    newSocket.close()

def tcpClient():
    
    print("THE TCP CLIENT Start###################")
    clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    clientSocket.connect((IPADDR, TCPPORT))

    while True:
        clientSocket.send(b"aaaaaaaaaa")

        recvdata = clientSocket.recv(2048)
        if len(recvdata):
            print("recvData:%s" % (recvdata.decode("gb2312")))

        time.sleep(2)
    
    clientSocket.close()
def udpServer():
    print("THE UDP SERVER Start##############")

    host_Addr_Port = (IPADDR, UDPPORT)
    serverSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)

    serverSocket.bind(host_Addr_Port)

    while True:
        recvData, clientAddr_Port = serverSocket.recvfrom(1024)
        if len(recvData.strip()) <= 0:
            print("UDP 客户端已经关闭!")
        else:
            print("received data is %s from %s"%(recvData, str(clientAddr_Port)))

def udpClient():

    print("THE UDP CLIENT Start##############")
    host_Addr_port = (IPADDR, UDPPORT)

    clientSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)

    sendData = b"HEllo! UDPSERVER"
    while True:

        clientSocket.sendto(sendData, (host_Addr_port))

        print("sendto OK")

        time.sleep(2)

    clientSocket.close()

def unixServer():
    print("THE UNIX SERVER Start#############")

    serverSocket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

    localDic = "/tmp/socket"

    if not os.path.exists(localDic):
        os.mknod(localDic)

    if os.path.exists(localDic):
        os.unlink(localDic)

    serverSocket.bind(localDic)

    serverSocket.listen(5)


    clientSocketUnix, clientInfoUnix = serverSocket.accept()
    print("客户端已经连接...")
    while True:
        recvData = clientSocketUnix.recv(2048)
        if len(recvData.strip()) ==  0:
           print("connection is break")
           break
        else:

           print("client said is %s "%(recvData))
        time.sleep(1)

    clientSocketUnix.close()
    serverSocket.close()

def unixClient():
    print("AF_UNIX Client Start##############")

    clientSocket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

    localPath = "/tmp/socket"

    clientSocket.connect(localPath)


    sendbuf = "Hello!unix server!i am client".encode("utf-8")
    while True:
        clientSocket.send(sendbuf)

        print("send OK!")

        time.sleep(1)

    clientSocket.close()

def getInfo_MAC_IP_TCP():
    print("AF_PACKET 嗅探以太网帧###################")


    rawSocket = socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(0x0800))

    while True:

        pkt = rawSocket.recvfrom(2048)

        ethernetHeader = pkt[0][0:14]   #提取以太网帧头
        eth_hdr = struct.unpack("!6s6s2s",ethernetHeader) #6字节目的mac地址,6字节源mac地址,2字节协议类型

        binascii.hexlify(eth_hdr[0])
        binascii.hexlify(eth_hdr[1])
        binascii.hexlify(eth_hdr[2])

        ipHeader = pkt[0][14:34]        #提取IP协议头,不包含option和padding字段。
        ip_hdr = struct.unpack("!12s4s4s",ipHeader)         # !标示转换网络字节序,前12字节为版本、头部长度、服务类型、总长度、标志等其他选项,后面的两个四字节依次为源IP地址和目的IP地址。

        print ("source IP address: " + socket.inet_ntoa(ip_hdr[1]))

        print ("destination IP address: " + socket.inet_ntoa(ip_hdr[2]))

        tcpHeader = pkt[0][34:54]
        tcp_hdr = struct.unpack("!HH16s",tcpHeader)

        print (tcp_hdr)
        time.sleep(2)

    rawSocket.close()

class fileRW():


    def getIniFile(path):
        iniFileList = []
        dirList = os.listdir(path)
        for file in dirList:
            if file.endswith(".ini") or re.match(r"\w+\.ini", file):
                iniFileList.append(file)
        openFile = open("case.log", "w")

        for file in iniFileList:
            filename = file.split('.')[0] + "\r\n"

            openFile.write(filename)

        return iniFileList
    def readIniFile():
        case_list = []
        with open('case.log', 'r') as fd:
            case_list = fd.read().split('\r\n').strip()
        print(case_list)
        return case_list

    def sendFileName(string):
        pass
        '''
        获取websocket套接字
        发送case文件名
        '''

def readFileToSend(path):
    systemList = []
    if os.path.isfile(path):
        with open(path, 'r') as fd:
            readinfo = fd.read()
        return readinfo

def main():
    choiceDic = {"T":tcpServer, "t":tcpClient, "U":udpServer, "u":udpClient, "X":unixServer, "x":unixClient, "G":getInfo_MAC_IP_TCP, 'W':servermain}
    print("message for using help################\n \
    T:TCP服务器\n \
    t:TCP客户端\n \
    U:UDP服务器\n \
    u:UDP客户端\n \
    X:AF_UNIX服务器\n \
    x:AF_UNIX客户端\n \
    G:获取以太网帧信息\n \
    W:TCP_WebSocket服务器 \
    q:Quit")

    while True:
        while True:
            try: 
            #先用strip()去掉空格
                choice = input("your choice:").strip()[0]
            except (EOFError, KeyboardInterrupt, IndexError): 
                choice = 'q'
            print('\nYou picked: [%s]' % choice) 
            if choice not in 'TtUuXxGqW': 
             print('Invalid option, try again')
            else: 
                break
        if choice is "q":
            break
        else:
            choiceDic[choice]()


if __name__ == "__main__":
    global IPADDR 
    global TCPPORT 
    global UDPPORT
    global WEBPORT
    global UNIX_LOACL_FILE
    IPADDR = "10.4.0.63"
    TCPPORT = 8899
    UDPPORT = 8444
    UNIX_LOACL_FILE = "/tmp/socket"
    WEBPORT = 8000
    print("IP:10.4.0.63")
    print("TCPPORT : 8899")
    print("UDPPORT : 8444")
    print("UNIX_LOACL_FILE:/tmp/socket")
    print("WebSocket ip:localhost \n \
           port:8000")
    
    caseList = getIniFile('../../test/')
    systemInfo = readFileToSend('../../system.log')
    print(systemInfo)

    ipChange = input("Do you want to change IP? ").strip()[0].lower()
    if ipChange == "y":
        IPADDR = input("the ip  you need is:").strip()

    tportChange = input("Do you want to change TCPPORT?").strip()[0].lower()
    if tportChange == "y":
        TCPPORT = int(input("the TCPPORT you need is :").strip())

    uportChange = input("Do you want to change UDPPORT?").strip()[0].lower()
    if uportChange == "y":
        UDPPORT = int(input("the UDPPORT you need is :").strip())

    webPort = input("Do you want to change WebSocket Server Port?").strip().lower()
    if webPort == 'y':
        WEBPORT = int(input('the WEBPORT you need is :').strip())

    
    main()



 

你可能感兴趣的:(python,网络)