Python Socket编程详解

栏目: Python · 发布时间: 9年前

内容简介:Python Socket编程详解

@author StormMa

@date 2017-06-10

生命不息,奋斗不止!

今天,来总结一下 Python 中Socket编程的部分,首先申明一下Python的版本是3.5

开始之前

我想学习Socket之前,你应该去看看什么是Socket,Socket通信是怎么一个流程,我想只有了解这些之后,你才能更好地掌握Socket编程,这里我就引用一个图,来大致的说明一下Socket通信的流程,具体的东西我希望你去google上去查:

Python Socket编程详解

简要的说明一下上面的图片吧(上面图片引用自 张岩林的博客 ),要想进行Socket通信,首先我们必须有一个Server端来处理连接请求(在python中创建一个服务端的Socket我们稍后给出方法),然后设置监听地址,然后处于阻塞状态,等待连接(accept函数),如果此时有客户端连接,然后服务端接入进行通信。如果了解 java 的话,可以参考我csdn上针对Java Socket讲解(说是讲解,其实就是贴了一段代码,尴尬脸)。Java中Socket编程总结

我想在开始讲解创建服务端和客户端的Socket之前,我应该讲一下Socket的申明:

socket(family=AF_INET, type=SOCK_STREAM, proto=0)

对于套接族类型 family 的可选值:

socket类型 描述
socket.AF_UNIX 用于同一台机器上的进程通信(既本机通信)
socket.AF_INET 用于服务器与服务器之间的网络通信(指定使用IPv4)
socket.AF_INET6 基于IPV6方式的服务器与服务器之间的网络通信
socket.SOCK_STREAM 基于TCP的流式socket通信
socket.SOCK_DGRAM 基于UDP的数据报式socket通信
socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次SOCK_RAW也可以处理特殊的IPV4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头
socket.SOCK_SEQPACKET 可靠的连续数据包服务

这些玩意没什么好说的,我们今天就用基于Tcp的IPv4的套接族来做演示

创建一个TCP Socket

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

在开始正式编码之前,我想我应该说一下Socket的常用的方法(贴一下API, 嘿哈!)

服务端Socket的方法

s.bind(address)
  将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。
s.listen(backlog)
  开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。
s.setblocking(bool)
  是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。
s.accept()
  接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。
  接收TCP 客户的连接(阻塞式)等待连接的到来

客户端Socket的方法

s.connect(address)
  连接到address处的套接字。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
s.connect_ex(address)
  同上,只不过会有返回值,连接成功时返回 0 ,连接失败时候返回编码,例如:10061

公共Socket的方法

s.close()
  关闭套接字
s.recv(bufsize[,flag])
  接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。
s.recvfrom(bufsize[.flag])
  与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
s.send(string[,flag])
  将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。
s.sendall(string[,flag])
  将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
   内部通过递归调用send,将所有内容发送出去。
s.sendto(string[,flag],address)
  将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。
s.settimeout(timeout)
  设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 client 连接最多等待5s )
s.getpeername()
  返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
s.getsockname()
  返回套接字自己的地址。通常是一个元组(ipaddr,port)
s.fileno()
  套接字的文件描述符
s.setblocking(flag)
    如果flag为0,则将套接字设置为非阻塞模式,否则将套接字设置为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数  据,或send()调用无法立即发送数据,那么将引起socket.error异常。

服务端Socket的实现

伪代码

# 创建一个socket
s = socket()
# 绑定地址和端口,参数元组
s.bind() 
# 监听
s.listen()
while True:
    # 阻塞式连接
    accept()
from socket import socket
from socket import AF_INET
from socket import SOCK_STREAM
from time import ctime

HOST = '127.0.0.1'
PORT = 5057
BUFFERSIZE = 1024
ADDRESS = (HOST, PORT)


def create_server_socket():
    """创建一个服务端Sockett,并且监听本地5257端口
    """
    tcp_socket = socket(AF_INET, SOCK_STREAM)
    tcp_socket.bind(ADDRESS)
    # 设置最大连接数为10
    tcp_socket.listen(10)
    return tcp_socket


def server_socket_start_work(server_tcp_socket):
    """服务端开始工作
    """
    print("等待客户端的链接")
    while True:
        tcp_client_socket, addr = server_tcp_socket.accept()
        print("有客户端连接")
        # 接收发送的数据
        while True:
            data = tcp_client_socket.recv(BUFFERSIZE)
            if not data:
                break
            tcp_client_socket.send(bytes('[%s] %s' % (ctime(), data), encoding='utf-8'))
            tcp_client_socket.close()
    server_tcp_socket.close()

if __name__ == '__main__':
    server_socket = create_server_socket()
    server_socket_start_work(server_socket)

客户端Socket的实现

伪代码

cs = socket()
cs.connect()
while True:
    cs.send()
cs.close()
from socket import socket
from socket import AF_INET
from socket import SOCK_STREAM
HOST = '127.0.0.1'
PORT = 5057
BUFFERSIZE = 1024
ADDRESS = (HOST, PORT)

tcp_client_socket = socket(AF_INET, SOCK_STREAM)
tcp_client_socket.connect(ADDRESS)

while True:
    data = input(">")
    if not data:
        break
    tcp_client_socket.send(bytes(data, encoding="utf-8"))
    data = tcp_client_socket.recv(BUFFERSIZE)
    if not data:
        break
    print(data)
tcp_client_socket.close()

先启动server_socket,然后开启client_socket, 本文来自我的个人站点: http://blog.stormma.me ,转载请注明出处!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。

DOM Scripting

DOM Scripting

Jeremy Keith / friendsofED / 2010-12 / GBP 27.50

There are three main technologies married together to create usable, standards-compliant web designs: XHTML for data structure, Cascading Style Sheets for styling your data, and JavaScript for adding ......一起来看看 《DOM Scripting》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具