一、Socket编程概述
python中提供socket.py标准库,非常底层的接口库。socker是一种通用的网络编程接口,和网络层次没有一一对应的关系。
socket可以跨操作系统,适合于任何类型的操作系统。
socket支持TCP与UDP协议。
服务的端口是由“进程”管理的,而不是由“线程”管理。
socket的定位?
socket是应用层与传输层之间的桥梁。
1个socket会占用一个文件描述符。fd=13
1、约定协议族:AF,用于socket()第一个参数
AF_INET--->IPV4
AF_INET6--->IPV6
2、socket类型
sock_STREAM-->TCP协议
sock_DGRAM-->UDP协议
3、TCP编程
服务器端:socket()->bind(ip,port)->listen()->accept(阻塞等待客户端连接,重新分配1个新的socket)->recvie()->send()-recvie()->close()
accept:允许接受请求,创建一系列新的socket连接。
客户端:socket()->connect()->send()-recvie()->close()
accept和recv都是阻塞的。主线程经常被阻塞而不能工作。
4、关键方法的说明
socket.recv(bufsize):获取数据。默认是阻塞的方式。
socket.recvfrom(bufsize):获取数据,返回一个二元组。
socket.recv_into(buffer):返回接收数据的字节数,如果没有就指定为0
socket.recvfrom_into(buffer):返回一个二元组(bytes,address)到buffer中去。
socket.send(bytes):TCP发送数据
socket.sendall(bytes):TCP发送全部数据,成功返回None
s.sendto(string,address):UDP发送数据
socket.sendfile(file,offset=0,count=None):发送一个文件直到EOF,使用高性能的os.sendfile机制,返回发送的字节数。
二、server端代码
from socket import * from time import ctime HOST = "127.0.0.1" PORT = 21000 BUFSIZE = 1024 #发送数据的缓冲区 ADDR = (HOST,PORT) tcpSerSock = socket(AF_INET,SOCK_STREAM) #此处用常用的AF_INET[ipv4],第二个参数是流套接字,即TCP tcpSerSock.bind(ADDR) #套接字与地址绑定 tcpSerSock.listen(5) #开始监听,参数表示允许的最大连接数 while True: print('waiting for connection...') tcpCliSock,addr = tcpSerSock.accept() #接客,accept返回一个二元组(connection,address),第一个新的socket对象,服务器必须通过它与客户通信;第二个是客户的地址。 print('...connnecting from:',addr) while True: data = tcpCliSock.recv(BUFSIZE) #接收数据,把话记录到data中。 if not data: #接收完毕,退出。 break tcpCliSock.send(('[%s] %s' % (ctime(), data)).encode()) #发送当前时间,以及数据给客人 tcpCliSock.close() #关闭与该客人通信的套接字。 tcpSerSock.close() #因为上面是死循环,此处不是必须的,只是提醒大家离开的时候务必要关门
三、client端代码
from socket import * HOST = '127.0.0.1' #因为我是在同一台机器上运行,所以是localhost,不同主机的话,此处需要改成服务器地址 PORT = 21000 BUFSIZ =1024 ADDR = (HOST,PORT) tcpCliSock = socket(AF_INET,SOCK_STREAM) #客户端只需要一个套接字 tcpCliSock.connect(ADDR) #发起连接 while True: data1 = input('>') if not data1: #数据发送完毕,关闭。 break tcpCliSock.send(data1.encode()) #发送数据 data1 = tcpCliSock.recv(BUFSIZ) #接收数据 if not data1: break print(data1.decode('utf-8')) tcpCliSock.close()