之前用java做过套接字编程,现在在学python,想试试python的套接字编程,做了一个小的基础的单线程demo 来解释socket编程。

对于套接字编程,了解更多的就是TCP和UDP两种协议,下面将在基于python的环境下使用两种协议写个小demo


流程如下:

1.一台客户机从其标准输入(键盘)读入一行字符,并通过其套接字将该行发送到服务器。

2.服务器从其连接套接字读取一行字符。

3.服务器将该行字符是否为退出命令,如果是,则关闭服务器,如果不是,服务器则通过连接套接字在发回一串字符到客户机。

4.客户机从其套接字中读取发回的行,然后将该行在其标准输出(监视器)上打印出来。


- TCP篇

# coding: utf-8
# python TCP套接字编程 服务器端

import socket


# TCP逻辑处理函数
def tcp(connection, address):
    print ("add a new client from %s:%s." % address)
    while True:
        try:
            connection.settimeout(5)  # 设置连接超时
            data = connection.recv(1024)
            if not data or data == 'quit':  # 如果发来数据为空或者quit 则退出
                print "quit! cut connection..."
                break
            else:
                print ("server received a string:%s." % data)  # 打印服务器接收到的数据
                connection.send('welcome to server!')  # 发送数据到客户端
        except socket.timeout:
            print "time out..."
            break
    connection.close()  # 关闭连接


def main():
    # 创建socket (AF_INET:IPv4, AF_INET6:IPv6) (SOCK_STREAM:面向流的TCP协议)
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost', 8888))   # 绑定本机IP和任意端口(>1024)
    sock.listen(5)    # 监听,等待连接的最大数目为5
    print "Server is running..."

    while True:
        connection, address = sock.accept()  # 接收一个连接,或许连接
        tcp(connection, address)  # 调用TCP逻辑处理函数


if __name__ == '__main__':
    main()
# coding: utf8
# python TCP套接字编程  客户端

if __name__ == "__main__":
    import socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   # 创建一个socket
    sock.connect(('localhost', 8888))  # 连接ip和端口  与服务器端相同
    import time
    time.sleep(1)    # 线程睡眠1秒钟后可发送数据

    while True:

        data = raw_input("input a string to server:")  # 输入数据,发送到服务器端,quit为退出

        if not data or data == 'quit':
            break

        sock.send(data)  # 发送数据到服务器端
        '''
        打印服务器发送来的数据, 设置接收最大字节,如果接收到的数据大于该阀值,
        则客户端只能接收到前面该阀值大小的数据,后面的数据将丢失
        '''
        print sock.recv(1024)    # 打印数据
    sock.send(b'quit')  # 发送退出指令到服务器端
    sock.close()        # 关闭连接

运行结果:

服务器端 –

python 使用socket抓udp包怎么才能达到wireshark那样地的丢包率_数据

客户机端–

python 使用socket抓udp包怎么才能达到wireshark那样地的丢包率_数据_02



- UDP篇
UDP协议不需要先建立连接,根据地址和端口直接互相发送数据即可。

# coding: utf-8
# python UDP套接字编程 服务器端

import socket


def main():
    # 创建socket (AF_INET:IPv4, AF_INET6:IPv6) (SOCK_DGRAM:面向流的UDP协议)
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(('localhost', 8888))   # 绑定本机IP和任意端口(>1024)

    print "UDP on 8888..."

    while True:
        recvData, address = sock.recvfrom(1024)        # 获得数据和客户端的地址与端口, 一次最大接收1024字节
        print "server is received data:", recvData, "from", ("%s:%s." % address)
        sock.sendto("ok! I got it.", address)    # 发回数据到客户机端

if __name__ == '__main__':
    main()
# coding: utf8
# python UDP套接字编程  客户端

if __name__ == "__main__":
    import socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)   # 创建一个socket, SOCK_DGRAM代表为UDP
    address = ('localhost', 8888)  # 服务器端地址
    import time
    time.sleep(1)    # 线程睡眠1秒钟后可发送数据

    while True:

        data = raw_input("input a string to server:")  # 输入数据,发送到服务器端,quit为退出

        if not data or data == 'quit':
            break

        sock.sendto(data, address)  # 发送数据到服务器端
        '''
        打印服务器发送来的数据, 设置接收最大  字节,如果接收到的数据大于该阀值,
        则客户端只能接收到前面该阀值大小的数据,后面的数据将丢失
        '''
        recvData, address = sock.recvfrom(1024)    # 接收服务器端发来的数据
        print ("data from server %s:%s is:" % address), recvData

    sock.close()        # 关闭连接

运行结果:

服务器端 –

python 使用socket抓udp包怎么才能达到wireshark那样地的丢包率_socket_03

客户机端–

python 使用socket抓udp包怎么才能达到wireshark那样地的丢包率_数据_04