Python网络编程(Sockets)

Python网络编程(Sockets)

Python提供了两个级别的访问网络服务。 在低级别,可以访问底层操作系统中的基本套接字支持,这允许您实现面向连接和无连接协议的客户端和服务器。

Python还具有提供对特定应用级网络协议(如FTP,HTTP等)的更高级别访问的库。

本章将了解和学习网络中最着名的概念 - 套接字编程。

1.什么是套接字?

套接字(Sockets)是双向通信信道的端点。 套接字可以在一个进程内,在同一机器上的进程之间,或者在不同主机的进程之间进行通信,主机可以是任何一台有连接互联网的机器。

套接字可以通过多种不同的通道类型实现:Unix域套接字,TCP,UDP等。 套接字库提供了处理公共传输的特定类,以及一个用于处理其余部分的通用接口。

套接字有自己的术语 -

  • domain - 用作传输机制的协议族。这些值是常量,例如:AF_INETPF_INETPF_UNIXPF_X25等。

  • type - 两个端点之间的通信类型,通常用于面向连接的协议的SOCK_STREAM和用于无连接协议的SOCK_DGRAM

  • protocol - 通常为0,这可以用于标识域和类型中的协议的变体。
  • hostname - 网络接口的标识符 -
    • 一个字符串,可以是一个主机名,一个有四个点符号的IP地址,或一个冒号中的IPV6地址(可能是点)符号。
    • 一个字符串“<broadcast>”,它指定一个INADDR_BROADCAST地址。
    • 零长度字符串,指定INADDR_ANY,或
    • 整数,以主机字节顺序解释为二进制地址。
  • port - 每个服务器监听一个或多个端口的客户端的调用。端口可能是Fixnum端口号,包含端口号的字符串或服务名称。

2. socket模块

要创建套接字,必须使用套接字模块中的socket.socket()函数,该函数具有一般语法 -

s = socket.socket (socket_family, socket_type, protocol = 0)

这里是上述参数的描述 -

  • socket_family - 它的值可以是:AF_UNIXAF_INET,如前所述。
  • socket_type - 它的值可以是:SOCK_STREAMSOCK_DGRAM
  • protocol - 这通常被省略,默认为0

当创建了套接字对象这后,就可以使用所需的函数来创建客户端或服务器程序。 以下是所需函数的列表:

服务器套接字方法

编号 方法 描述
1 s.bind() 此方法将地址(主机名,端口号对)绑定到套接字。
2 s.listen() 此方法设置并启动TCP侦听器。
3 s.accept() 这被动地接受TCP客户端连接,等待直到连接到达(阻塞)。

客户端套接字方法

编号 方法 描述
1 s.connect() 此方法主动启动TCP服务器连接。

通用套接字方法

编号 方法 描述
1 s.recv() 此方法接收TCP消息。
2 s.send() 该方法发送TCP消息
3 s.recvfrom() 此方法接收UDP消息
4 s.sendto() 此方法发送UDP消息
5 s.close() 此方法关闭套接字
6 socket.gethostname() 返回主机名

3.一个简单的服务器

要编写互联网服务器,可使用socket模块中可用的socket()来创建套接字对象。 然后使用套接字对象调用其他函数来设置套接字服务器。

现在调用bind(hostname,port)函数来指定主机上服务的端口。

接下来,调用返回对象的accept()方法。 此方法在您指定的端口等待客户端连接,连接成功后返回一个连接(connection)对象,该对象表示与该客户端的连接。

#!/usr/bin/python3           # This is server.py file
import socket

# create a socket object
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# get local machine name
host = socket.gethostname()                           

port = 8088

# bind to the port
serversocket.bind((host, port))                                  
print("Server start at port: 8088")
# queue up to 5 requests
serversocket.listen(5)                                           

while True:
    # establish a connection
    clientsocket,addr = serversocket.accept()      

    print("Got a connection from %s" % str(addr))

    msg='Thank you for connecting'+ "\r\n"
    clientsocket.send(msg.encode('ascii'))
    clientsocket.close()

4.一个简单的客户端

下面接着编写一个非常简单的客户端程序,打开与给定端口8088与上面的服务器程序主机的连接。 使用Python的socket模块功能创建套接字客户端非常简单。

socket.connect(hosname,port)函数打开hostname上的port的TCP连接。当打开了一个套接字,就可以像任何IO对象一样读取它。 完成后,请记住关闭它,就像关闭文件一样。

示例

以下代码是连接到给定主机和端口的非常简单的客户端,从套接字读取任何可用数据,然后退出 -

#!/usr/bin/python3           # This is client.py file

import socket

# create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# get local machine name
host = socket.gethostname()

port = 8088

# connection to hostname on the port.
s.connect((host, port))

# Receive no more than 1024 bytes
msg = s.recv(1024)

s.close()

print (msg.decode('ascii'))

现在在后台运行先运行:server.py,然后运行上面的client.py来查看结果,如果程序没有错误,那么应该得到类似以下以结果 -

5. Python互联网模块

Python网络/互联网编程中的一些重要模块的列表如下:

协议 通用功能 端口号 对应Python模块
HTTP 网页服务 80 httplib, urllib, xmlrpclib
NNTP Usenet新闻 119 nntplib
FTP 文件传输 20 ftplib, urllib
SMTP 发送邮件 25 smtplib
POP3 获取电子邮件 110 poplib
IMAP4 获取电子邮件 143 imaplib
Telnet 命令行 23 telnetlib
Gopher 文档传输 70 gopherlib, urllib

请检查上述所有库,以使用FTP,SMTP,POP和IMAP协议。

进一步阅读

这是Socket编程的一个快速开始。 这是一个广阔的话题。 建议通过以下链接查找更多详细信息 -