python网络套接字_Python网络编程-socket套接字

套接字对象(内置)方法

13b7d6edff124a6f9c98ea54c233eab1.png

socket()模块函数

要创建套接字,必须用socket.socket()函数socket(socket_family,socket_type,protocol=0)其中,socket_family是AF_UNIX或AF_INET,socket_type是SOCK_STREAM(TCP)或SOCK_DGRAM(UTP)。protocal通常为0.

创建TCP服务器

通用的TCP服务器的一般伪代码

ss = socket() #创建服务器套接字

ss.bind() #套接字与地址绑定

ss.listen() #监听连接

inf_loop: #服务器无线循环

cs = ss.accept() #接收客户端连接

comn_loop: #通讯循环

cs.recv()/cs.send() #对话(接收/发送)

cs.close() #关闭客户端套接字

ss.close() #关闭服务器套接字#(可选)

所有套接字都是通过使用socket.socket()函数来创建的。因为服务器需要占用一个端口并等待客户端的请求,所以它们必须绑定一个本地地址。因为TCP是一个面向连接的通讯系统,所以在TCP服务器开始操作之前,必须安装一些基础设施。特别的,TCP服务器必须监听(传入)的连接。一旦这个安装过程完成之后,服务器就可以开始它的无限循环。

创建TCP服务器(代码)

#!/usr/bin/env python

# -*- coding: utf-8 -*-

from socket import *

from time import ctime

ss = socket()

HOST = '' #表示可以使用任何可用的地址

PORT = 21567 #选择一个端口号 >1024 小于1024的端口号预留给了系统

BUFSIZE = 1024 #设置缓冲区的大小1KB 可调节

ADDR = (HOST,PORT) #元组 存放 IP 和端口号

tcpSerSock = socket(AF_INET,SOCK_STREAM) #分配TCP服务器套接字

tcpSerSock.bind(ADDR) #将套接字绑定到服务器地址(主机名,端口号对)

tcpSerSock.listen(5) #设置并启动TCP监听器 并传入连接请求的最大值(5只是个估计值,并不一定准确)

while True:

print('waiting for connenct ...')

#tcpCliSock 客户端连接套接字 addr 客户端 IP 和端口信息

tcpCliSock,addr = tcpSerSock.accept() #被动等待客户端发送消息

print('...connect from :',addr)

while True :

data = tcpCliSock.recv(BUFSIZE) #接收 缓冲区中存储的客户端发过来的数据

if not data :

break

tcpCliSock.send(bytes('[%s] %s' %(ctime(),data),'utf-8')) #将结果return 给客户端

tcpCliSock.close() #关闭客户端

tcpSerSock.close() #关闭服务端 永远不会被执行。如果要在某条件下退出服务器,可以考虑使用close()

socket缓冲区BUFSIZ

每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区。

write()/send() 并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器。一旦将数据写入到缓冲区,函数就可以成功返回,不管它们有没有到达目标机器,也不管它们何时被发送到网络,这些都是TCP协议负责的事情。

TCP协议独立于 write()/send() 函数,数据有可能刚被写入缓冲区就发送到网络,也可能在缓冲区中不断积压,多次写入的数据被一次性发送到网络,这取决于当时的网络情况、当前线程是否空闲等诸多因素,不由程序员控制。

read()/recv() 函数也是如此,也从输入缓冲区中读取数据,而不是直接从网络中读取。

ba4dc469b57349c08855a8e70ff4b988.jpg

图:TCP套接字的I/O缓冲区示意图

这些I/O缓冲区特性可整理如下:

1. I/O缓冲区在每个TCP套接字中单独存在;

2. I/O缓冲区在创建套接字时自动生成;

3. 即使关闭套接字也会继续传送输出缓冲区中遗留的数据;

4. 关闭套接字将丢失输入缓冲区中的数据。

TCP套接字的阻塞模式

对于TCP套接字(默认情况下),当使用 write()/send() 发送数据时:

1. 首先会检查缓冲区,如果缓冲区的可用空间长度小于要发送的数据,那么 write()/send() 会被阻塞(暂停执行),直到缓冲区中的数据被发送到目标机器,腾出足够的空间,才唤醒 write()/send() 函数继续写入数据。

2. 如果TCP协议正在向网络发送数据,那么输出缓冲区会被锁定,不允许写入,write()/send() 也会被阻塞,直到数据发送完毕缓冲区解锁,write()/send() 才会被唤醒。

3. 如果要写入的数据大于缓冲区的最大长度,那么将分批写入。

4. 直到所有数据被写入缓冲区 write()/send() 才能返回。

当使用 read()/recv() 读取数据时:

1. 首先会检查缓冲区,如果缓冲区中有数据,那么就读取,否则函数会被阻塞,直到网络上有数据到来。

2. 如果要读取的数据长度小于缓冲区中的数据长度,那么就不能一次性将缓冲区中的所有数据读出,剩余数据将不断积压,直到有 read()/recv() 函数再次读取。

3. 直到读取到数据后 read()/recv() 函数才会返回,否则就一直被阻塞。

socket连接请求listen(*)

listen表示在拒绝新的连接之前,系统可以挂起的最大连接数量,这些连接还没有被accept方法接收到。

创建TCP客户端

通用的TCP客户端的一般伪代码

cs = socket() #创建客户端套接字

cs.connect() #尝试连接服务器

comn_loop: #通讯循环

cs.send()/cs.recv() #对话(发送/接收)

cs.close() #关闭客户端套接字

所有的套接字全部利用socket.socket()创建的。一旦客户端拥有了一个套接字,它就可以利用套接字的connect()方法直接创建一个到服务器的连接,当连接创建之后,他就可以参与到服务器的一个对话中。

创建TCP客户端(代码)

#!/usr/bin/env python

# -*- coding: utf-8 -*-

from socket import *

HOST = 'localhost'

PORT = 21567

BUFSIZE =1024

ADDR = (HOST,PORT)

tcpCliSock = socket(AF_INET,SOCK_STREAM) #创建套接字

tcpCliSock.connect(ADDR) #连接套接字

while True:

data = input('> ') #输入内容

if not data:

break

tcpCliSock.send(data.encode()) #发送输入内容

data = tcpCliSock.recv(BUFSIZE) #接收服务端处理结果

if not data:

break

print(data)

tcpCliSock.close()

多线程处理客户端请求

该例子没有实现多线程,仅是半双工模式,当建立一个连接且服务开始后,只有一个客户端在得到输入信息提示后进行会话,其他客户端处于等待状态。多线程可以使用socketserver模块,它支持客户端请求的线程和多线程处理。

参考文献:

TCP套接字

Socket

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值