Skip to content

Files

Latest commit

8e2c875 · Nov 20, 2019

History

History
190 lines (131 loc) · 5.16 KB

72.md

File metadata and controls

190 lines (131 loc) · 5.16 KB

Python 网络套接字编程教程

原文: https://pythonspot.com/python-network-sockets-programming-tutorial/

在本教程中,您将学习网络编程。您将了解用于万维网,电子邮件和许多其他应用程序的客户端-服务器模型。

client server

客户端服务器(带有电子邮件协议)客户端服务器模型是一个模型,其中有 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

下载套接字代码