原文: https://pythonspot.com/python-network-sockets-programming-tutorial/
在本教程中,您将学习网络编程。您将了解用于万维网,电子邮件和许多其他应用程序的客户端-服务器模型。
客户端服务器(带有电子邮件协议)客户端服务器模型是一个模型,其中有 n 个客户端和一个服务器。 客户端向服务器发出数据请求。 服务器回复收到的那些消息。 客户端可以是任何设备,例如您的计算机或平板电脑。 服务器通常是要 24/7 连接的专用计算机。
此代码将使用套接字启动一个简单的 Web 服务器。 它等待连接,如果接收到连接,它将输出接收到的字节。
#!/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:
$ python server.py
将在端口 62 处打开 Web 服务器。 在第二个屏幕中,使用 Telnet 打开客户端。 如果将同一台计算机用于客户端和服务器,请使用:
$ telnet 127.0.0.1 62.
如果将另一台计算机用作客户端,请键入该计算机的相应 IP 地址。您可以使用ifconfig
找到它。
您从客户端编写的所有内容都将到达服务器。 服务器将收到的消息发回。下面是一个示例输出(单击放大)
下面的客户端脚本将消息发送到服务器。 服务器必须正在运行!
#!/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 中所做的行为。
上面的服务器代码只能与一个客户端交互。 如果您尝试连接第二个终端,则根本不会回复新客户端。 要使服务器与多个客户端交互,您需要使用多线程。 我们重建服务器脚本以接受多个客户端连接:
#!/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()
到目前为止,我们只是来回发送了消息。每个消息在应用程序中可以具有特定的含义。这就是所谓的协议。这些消息的含义在发送方和接收方都必须相同。下面的传输层确保接收到消息(TCP)。网络层是 IPv4 协议。我们需要定义的只是应用层。
下面我们修改了服务器以接受简单命令(为简单起见,我们使用非线程服务器)。我们将端口更改为 64。带有协议的服务器代码:
#!/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()
使用以下命令运行服务器:
sudo python server.py
然后,客户端可以与 telnet 连接(确保选择正确的 IP):
$ 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