python3网络编程实例_python3网络编程:socket的简单使用

01.套接字

套接字用于应用程序间的通信,任何程序间的通信开始之前都要创建套接字

有两种类型的套接字:基于文件的和面向网络的。

套接字最初是为同一主机上的应用程序所创建,使得主机上运行的一个进程和另一个进程进行通信,也就是进程间通信(IPC Inter Process Communication)。

文件套接字:

Unix套接字是套接字的第一个家族,家族名AF_UNIX(又名AF_LOCAL),家族名代表地址家族(address family)

网络套接字:

网络套接字也有自己的家族名,AF_INET,另一个地址家族AF_INET6是用于ipv6寻址。还有一些其他的地址家族,但是目前使用最广泛的是AF_INET

python支持AF_UNIX.AF_NETLINK,AF_TIPC,AF_INET几个家族。对于网络编程来说,我们将使用AF_INET.所以接下来讨论的内容都是AF_INET家族的套接字

套接字地址有主机号(ip)和端口号两个部分组成,有效端口号的范围是0~65535,小于1024的端口号是系统预留的,所以我们写程序的时候不要去占用。

02.面向连接的套接字和无连接的套接字

001.面向连接的套接字

面向连接的通信提供序列化的、可靠的和不重复的数据交付,没有记录边界。每条消息可以拆成多个片段,并且每一个消息片段都能确保到达目的地,然后将他们按顺序组合在一起,最后将完整消息传递给正在等待的应用程序。

主要就是传输控制协议tcp。

为了创建tcp套接字,必须使用SOCK_STREAM作为套接字类型。

002.无连接的套接字

不需要建立连接,也无法确保数据的顺序性,可靠性和重复性。

可以类比于邮政服务,信件和包裹也许并不能以发送顺序到达,也可能根本没有到达。

相对于面向连接服务,没有创建维持连接需要的成本,资源消耗更小,更快速。

主要是用户数据报协议UDP

为了创建UDP协议的套接字,必须使用SOCK_DGRAM作为套接字类型。

tcp和udp都是结合ip协议寻找互联网上的主机。所以这种系统被称为TCP/IP,UDP/IP

03.python 中的网络编程

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

socket_family是AF_UNIX或AF_INET,socket_type是SOCK_STREAM或SOCK_DGRAM。protocol通常省略,默认为0.

socket对象的其他方法接下来将通过实例来演示:

下面首先演示的是一个tcp时间戳服务器:

import socket

import time

HOST = ''

PORT = 21567

BUFSIZE = 1024

ADDR = (HOST,PORT)

# 创建服务端套接字用于接受客户端的连接

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

# 绑定本地端口

tcpSerSock.bind(ADDR)

# 设定允许连接的最大数值

tcpSerSock.listen(5)

while True:

print('waiting for connection,local address:',ADDR)

# accept方法接受客户端发送的请求,并且产生一个服务客户端用的socket,返回客户端的地址

tcpClientSock,addr = tcpSerSock.accept()

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

while True:

# 建立连接后,用tcpClientSock服务客户端,接受客户端发送的数据,使用指定大小的缓冲区

data = tcpClientSock.recv(BUFSIZE)

print('recieving data:',data)

# 当没有收到数据时退出循环

if not data:

break

# 在客户端发送的数据前加上时间戳再送回,socket需要放送bytes类型的数据,所以这里b是转化二进制数据

tcpClientSock.send(b'[%s] %s'%(bytes(time.ctime(),'utf-8'),data))

# 关闭服务客户端的socket

tcpClientSock.close()

# 关闭服务器的socket,现实情况下服务器都是一直运行的,所以一般不会关闭

tcpSerSock.close()

接下来是创建tcp客户端

创建客户端比服务器简单一些,

下面创建的客户端连接之前创建的服务器,向服务器发送数据,并且打印服务器返回的数据。

import socket

HOST = 'localhost'

PORT = 21567

BUFSIZE = 1024

ADDR = (HOST,PORT)

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

tcpCliSock.connect(ADDR)

while True:

data = input('> ')

if not data:

break

# socket需要放送bytes类型的数据,所以这里encode是转化二进制数据

tcpCliSock.send(data.encode('utf8'))

data = tcpCliSock.recv(BUFSIZE)

if not data:

break

print(data)

tcpCliSock.close()

接下来是创建udp服务器。由于是无连接的,所以并没有为了成功而使一个客户端连接到一个独立的套接字的“转换”操作。

import socket

import time

HOST = ''

PORT = 21567

BUFSIZE = 1024

ADDR = (HOST, PORT)

udpSerSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

udpSerSock.bind(ADDR)

while True:

print('waiting for message...')

data,addr = udpSerSock.recvfrom(BUFSIZE)

print('receiving data from %s,data:%s'%(addr,data))

sendstr='[%s] %s'%(time.ctime(),data)

udpSerSock.sendto(sendstr.encode('utf8'),addr)

print('...received from and returned to:',addr)

udpSerSock.close()

# 创建udp客户端

import socket

import time

HOST = 'localhost'

PORT = 21567

BUFSIZE = 1024

ADDR = (HOST, PORT)

udpCliSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

while True:

data = input('>')

if not data:

break

udpCliSock.sendto(data.encode('utf8'),ADDR)

data,addr = udpCliSock.recvfrom(BUFSIZE)

if not data:

break

print(data)

udpCliSock.close()

04.socketserver模块

socketserver是python标准库里面的一个高级模块,目标是简化创建客户端和服务器的代码。

下面我们先介绍tcp时间戳服务器的例子:

import socketserver

import time

HOST = ''

PORT = 21567

ADDR = (HOST,PORT)

class MyRequestHandler(socketserver.StreamRequestHandler):

def handle(self):

print('...connected from:',self.client_address)

self.wfile.write(('[%s] %s'%(time.ctime(),self.rfile.readline())).encode('utf8'))

tcpServ = socketserver.TCPServer(ADDR,MyRequestHandler)

print('waiting for connection...')

tcpServ.serve_forever()

客户端

import socket

HOST = 'localhost'

PORT = 21567

BUFSIZE = 1024

ADDR = (HOST,PORT)

while True:

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

tcpCliSock.connect(ADDR)

data = input('> ')

if not data:

break

tcpCliSock.send(('%s\r\n'%data).encode('utf8'))

data = tcpCliSock.recv(BUFSIZE)

if not data:

break

print(data.strip())

tcpCliSock.close()

用这个高级模块,自己带一些异常处理,可以检测到键盘中断了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值