# Python 网络套接字编程教程

> 原文： [https://pythonspot.com/python-network-sockets-programming-tutorial/](https://pythonspot.com/python-network-sockets-programming-tutorial/)

在本教程中，您将学习 [**网络编程**](https://pythonspot.com/en/network/) 。 您将了解用于万维网，电子邮件和许多其他应用程序的客户端-服务器模型。

![client server](img/7ebef81ff83b49c4f531247f8fb26cc7.jpg)

客户端服务器（带有电子邮件协议）_ 客户端服务器模型是一个模型，其中有 n 个客户端和一个服务器。 客户端向服务器发出数据请求。 服务器回复收到的那些消息。 客户端可以是任何设备，例如您的计算机或平板电脑。 服务器通常是要 24/7_ 连接的专用计算机。

### 套接字服务器代码

This code will start a simple web server using sockets. It waits for a connection and if a connection is received it will output the bytes received.

```py
#!/usr/bin/env python

import socket

TCP_IP = '127.0.0.1'
TCP_PORT = 62
BUFFER_SIZE = 20  # Normally 1024, but we want fast response

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)

conn, addr = s.accept()
print 'Connection address:', addr
while 1:
     data = conn.recv(BUFFER_SIZE)
     if not data: break
     print "received data:", data
     conn.send(data)  # echo
conn.close()

```

Execute with:

```py
$ python server.py

```

This opens the web server at port 62\. In a second screen, open a client with Telnet. If you use the same machine for the client and server use:

```py
$ telnet 127.0.0.1 62.

```

If you use another machine as client, type the according IP address of that machine. You can find it with ifconfig.

Everything you write from the client will arrive at the server. The server sends the received messages back. An example output below (Click to enlarge):

### 套接字网络客户端：

下面的客户端脚本将消息发送到服务器。 服务器必须正在运行！

```py
#!/usr/bin/env python

import socket

TCP_IP = '127.0.0.1'
TCP_PORT = 5005
BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
s.close()

print "received data:", data

```

该客户端仅模仿我们在 Telnet 中所做的行为。

## 服务器代码的限制

上面的服务器代码只能与一个客户端交互。 如果您尝试连接第二个终端，则根本不会回复新客户端。 要使服务器与多个客户端交互，您需要使用多线程。 我们重建服务器脚本以接受多个客户端连接：

```py
#!/usr/bin/env python

import socket
from threading import Thread
from SocketServer import ThreadingMixIn

class ClientThread(Thread):

    def __init__(self,ip,port):
        Thread.__init__(self)
        self.ip = ip
        self.port = port
        print "[+] New thread started for "+ip+":"+str(port)

    def run(self):
        while True:
            data = conn.recv(2048)
            if not data: break
            print "received data:", data
            conn.send(data)  # echo

TCP_IP = '0.0.0.0'
TCP_PORT = 62
BUFFER_SIZE = 20  # Normally 1024, but we want fast response

tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind((TCP_IP, TCP_PORT))
threads = []

while True:
    tcpsock.listen(4)
    print "Waiting for incoming connections..."
    (conn, (ip,port)) = tcpsock.accept()
    newthread = ClientThread(ip,port)
    newthread.start()
    threads.append(newthread)

for t in threads:
    t.join()

```

### 应用协议

So far we have simply sent messages back and forth. Every message can have a specific meaning in an application. This is known as the protocol. The meaning of these messages must be the same on both the sender and receiver side. The Transport Layer below makes sure that messages are received (TCP). The Internet Layer is the IPv4 protocol. All we have to define is the Application Layer.

下面我们修改了服务器以接受简单命令（为简单起见，我们使用非线程服务器）。 我们将端口更改为 64。带有协议的服务器代码：

```py
#!/usr/bin/env python

import socket

TCP_IP = '127.0.0.1'
TCP_PORT = 64
BUFFER_SIZE = 20  # Normally 1024, but we want fast response

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)

conn, addr = s.accept()
print 'Connection address:', addr
while 1:
     data = conn.recv(BUFFER_SIZE)
     if not data: break
     print "received data:", data
     #conn.send(data)  # echo
     if "/version" in data:
         conn.send("Demo versionn")

     if "/echo" in data:
         data = data.replace("/echo","")
         conn.send(data + "n")

conn.close()

```

使用以下命令运行服务器：

```py
sudo python server.py

```

然后，客户端可以与 telnet 连接（确保选择正确的 IP）：

```py
$ telnet 127.0.0.1 64
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
message
/version
Demo version
/echo Repeat this
 Repeat this

```

[下载套接字代码](https://pythonspot.com/en/download-code/?id=L3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE2LzA4L3NvY2tldHNUdXRvcmlhbC56aXA=)