Python Socket
Socket:
网络7层模型:
1.物理层:主要定义物理传输设备标准,如网线的接口类型,各种传输介质的传输速率等。
2.数据链路层:主要将物理层接受的数据进行MAC地址的封装与解封。
3.网络层:主要将从下层接收到的数据进行IP地址的封装与解封。
4.传输层:定义了一些传输数据的协议和端口号。
5.会话层:通过传输层建立数据传输的通路。
6.表示层:主要是进行对接收的数据进行解释加密与解密,压缩与解压。
7.应用层:一些终端的应用。
UDP特点:
.面向无连接:传输数据之前源端与目的端不需要建立连接
.每个数据报的大小都限制在64k(8字节)以内
.面向报文的不可靠协议
.传输速率快,效率高
.现实生活实例:实时在线聊天,视频会议
TCP特点:
.面向连接:传输数据之前需要建立连接
.在连接过程中进行大量数据传输
.通过三次握手的方式完成连接,是安全可靠的连接
.传输速度慢,效率低
socket创建:
sk.socket.socket(socket.AF_INET,socket.SCOK_STREAM,0)
1.地址簇
socket.AF_INET IPV4(默认)
socket.AF_INET6 IPV6
socket.AF_UNIX 只能用于单一的unix系统进程通信
2.类型
socket.SOCK_STREAM 流式socket ,for TCP(默认)
socket.SOCK_DGRAM 数据报socket , for UDP
socket通信流程:
sk.bind(address)->sk.bind(('127.0.0.1',8000))
#将套接字绑定到地址
sk.listen(backing)->sk.listen(5)
#开始监听传入连接,backing 可挂起的最大连接数量
sk.setblocking(False)
#是否阻塞,默认True,设置False时,accept和recv时一旦无数据,则报错。
conn,addr = sk.accept()
#接受并返回(conn,address),其中conn时套接字对象
sk.connect(('127.0.0.1',8000))
#连接到addr处的套接字,客户端
sk.connect_ex(('127.0.0.1'),8000)
#连接到addr处的套接字,连接成功时返回0,客户端
sk.close()
#关闭套接字
sk.recv(bufsize,[flag])
#接受套接字的数据,bufsize制定最多可以接收的数量,flag提供有关消息的其他信息
sk.recvfrom(bufsize,[flag])
#返回数据和发送数据的套接字地址 data,sddr = sk.recvfrom()
sk.send(string,[flag])
#将string中的数据发送到连接的套接字
sk.sendall(string,[flag])
#将string数据全部发送,内部通过递归调用send()方法
sk.sendto(string,[flag],address)
#将数据发送到之地address的套接字,该函数主要用于UDP协议
sk.settimeout(timeout)
#设置套接字操所的超时时间,timeout是一个浮点数,单位是秒
sk.getpeername()
#返回套接字的远程地址,返回元祖类型
sk.getsockname()
#返回套接字自己的地址
sk.fileno()
#套接字的文件描述符
#阻塞式socket
socket_sever.py
import socket
sk = socket.socket()
ip_port = ('127.0.0.1',8888)
sk.bind(ip_port)
sk.listen(5)
while True:
print('wait .....')
conn,addr = sk.accept()
while True:
try:
data = conn.recv(1024)
except Exception as e:
print('对方已经下线!')
break
print(str(data,encoding='utf8'))
while True:
inp = input('inp>>>:')
if len(inp)>0:
break
if inp == 'q':
conn.close()
break
conn.send(bytes(inp,encoding='utf8'))
sk.close()
------------------------------------------
socket_client.py
import socket
sk = socket.socket()
ip_port = ('127.0.0.1',8888)
sk.connect(ip_port)
while True:
inp = input('inp>>:')
if inp == 'q' or inp == '':
break
sk.send(bytes(inp,encoding='utf8'))
try:
data = sk.recv(1024)
except Exception as e:
print('对方已经下线!')
break
print(str(data,encoding='utf8'))
sk.close()
#并发,非阻塞式
server.py
import socketserver
class MyServer(socketserver.BaseRequestHandler):
def handle(self):
print('启动服务端:')
while True:
conn = self.request
print(self.client_address)
while True:
client_data = conn.recv(1024)
print(str(client_data,encoding='utf8'))
sever_response = input('>>>')
conn.sendall(bytes(sever_response,encoding='utf8'))
conn.close()
if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1',8899),MyServer)
server.serve_forever()
-----------------------------------
client.py
import socket
sk = socket.socket()
ip_port = ('127.0.0.1',8899)
sk.connect(ip_port)
print('客户端启动')
while True:
inp = input('>>>')
sk.sendall(bytes(inp,encoding='utf8'))
server_response = sk.recv(1024)
print(str(server_response,encoding='utf8'))
if inp == 'q':
break
sk.close()
注意:
1.一发一收
2.解决粘包的方式,就是在发送字符长度的时候,等待接收一个对方传过来的信号
3.5个server类
.BaseServer
.TCPServer ->UnixSreamServer (unix 系统下的TCP)
.UDPServer ->UnixDatagramServer (unix 系统下的UDP)
4.socketserver 并发
.socketserver.ForkingTCPServer (基于多进程的并发)
.socketserver.ForkingUDPServer
.socketserver.ThreadingTCPServer (基于多线程的并发)
.socketserver.ThreadingUDPServer

浙公网安备 33010602011771号