Rumah > pembangunan bahagian belakang > Tutorial Python > 使用Python Socket编程详解

使用Python Socket编程详解

高洛峰
Lepaskan: 2017-03-24 16:12:39
asal
1187 orang telah melayarinya

这篇文章主要介绍了Python Socket编程详细介绍,socket可以建立连接,传递数据,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。

在使用Python做socket编程时,由于需要使用阻塞(默认)的方式来读取数据流,此时对于数据的结束每次都需要自己处理,太麻烦。并且网上也没找到太好的封装,所以就自己写了个简单的封装。

封装思路

1. 客户端每次请求均发送一个 SocketRequest 对象,其中封装具体的数据,这里使用json。对于要发送的数据,会自动添加一个结束符标识(EOF = ‘0x00')。

2. 服务器端接收数据时,根据结束符标识来生成完整的数据,并解包成 SocketRequest 对象。

3. 服务器端根据 SocketRequest 的内容,来生成 SocketResponse 对象,这里使用了一个 SimpleRequestHandler 类来处理,例子中就是没有做任何处理,然后原样返回。

4. 服务器端发送 SocketResponse 给客户端。其中也需要对包做一个封装,会自动添加一个结束符标识(EOF = ‘0x00')。

5. 客户接收数据时,根据结束符标识来生成完整的数据,并解包成 SocketResponse 对象,然后返回。

封装类

sockets.py


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import socket

import pickle

import thread

 

 

PORT = 12345

EOF = '0x00'

 

 

class SocketServer(object):

 

  def __init__(self, port=None):

    self.port = port

 

  def startup(self):

    sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    sock_server.bind(('0.0.0.0', self.port))

    sock_server.listen(0)

 

    while True:

      sock, address = sock_server.accept()

      thread.start_new_thread(self.__invoke, (sock, address))

 

  def shutdown(self):

    pass

 

  def __invoke(self, sock, address):

    try:

      full_data = ''

      while True:

        data = sock.recv(1024)

        if data is None:

          return

 

        full_data += data

        if full_data.endswith(EOF):

          full_data = full_data[0:len(full_data) - len(EOF)]

          request = pickle.loads(full_data)

          response = SimpleRequestHandler().handle(request)

          sock.sendall(pickle.dumps(response) + EOF)

          return

    except Exception as e:

      print e

    finally:

      sock.close()

 

 

class SocketClient(object):

 

  def __init__(self, host, port):

    self.host = host

    self.port = port

 

  def execute(self, request):

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    sock.connect((self.host, self.port))

 

    try:

      sock.sendall(pickle.dumps(request) + EOF)

      full_data = ''

      while True:

        data = sock.recv(1024)

        if data:

          full_data += data

          if full_data.endswith(EOF):

            full_data = full_data[0:len(full_data) - len(EOF)]

            response = pickle.loads(full_data)

            return response

        else:

          return None

    except Exception as e:

      print e

      return None

    finally:

      sock.close()

 

 

class SocketRequest(object):

  def __init__(self, data):

    self.data = data

 

  def __repr__(self):

    return repr(self.__dict__)

 

 

class SocketResponse(object):

  def __init__(self, data):

    self.data = data

 

  def __repr__(self):

    return repr(self.__dict__)

 

 

class SimpleRequestHandler(object):

  def __init__(self):

    pass

 

  def __repr__(self):

    return repr(self.__dict__)

 

  def handle(self, request):

    return SocketResponse(request.data)

Salin selepas log masuk

测试

socket_server.py


1

2

3

4

5

6

#!/usr/bin/env python

# -*- coding: utf-8 -*-

from agent.sockets import *

 

ss = SocketServer(PORT)

ss.startup()

Salin selepas log masuk

socket_client.py


1

2

3

4

5

6

7

8

9

10

11

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import pickle

from agent.sockets import *

 

 

sc = SocketClient('localhost', PORT)

request = SocketRequest('abc')

response = sc.execute(request)

print request

print response

Salin selepas log masuk

运行测试

首先,运行 socket_server.py

然后,运行 socket_client.py

Atas ialah kandungan terperinci 使用Python Socket编程详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan