Python3 Socket

Socket

socket介绍

socket意为套接字,是应用层与传输层TCP/IP,UDP之间通讯的中间软件抽象层,它是一组接口。使用时只需遵循socket的格式与规定去编程,让socket组织数据以符合TCP/UDP协议进行数据的传输。python

img

socket的工做流程

img

先从服务端提及,服务端先初始化socket --> 为此socket绑定端口(bind) --> 监听此端口(listen) --> 调用accept阻塞socket,直到有客户端链接 --> 若是此时客户端链接成功(connect),即与服务端完整创建链接,便可开始发送数据请求(write) --> 服务器端接收请求并处理请求(read),而后把回应数据发送给客户端(write) --> 客户端读取响应内容(read) --> 关闭链接,交互结束(close)编程

scoket初始化->socket.socket()

socket.socket(socket_family,socket_type,protocal=0)缓存

socket_family

AF_INET(ipv4)
AF_INET6 (ipv6)
AF_UNIX(UNIX之间通讯,绝对路径名)

socket_type

#   SOCK_STREAM 提供有序的、可靠的、双向的和基于链接的字节流服务,当使用Internet地址族时使用TCP;通常为面向链接的TCP

#   SOCK_DGRAM 支持无链接的、不可靠的和使用固定大小(一般很小)缓冲区的数据报服务,当使用Internet地址族使用UDP;通常为非链接的UDP

#   SOCK_RAW 原始套接字,容许对底层协议如IP或ICMP进行直接访问,能够用于自定义协议的开发。

protocal

#	IPPROTO_TCP,TCP协议

# 	IPPROTO_UDP,UPD协议

# 	0,若是指定为0,表示由内核根据so_type指定默认的通讯协议

TCP/IP+ipv4

s.socket(socket.AF_INET, socket.SOCK_STREAM)

服务端套接字

s.bind()

用于绑定(主机/ip,端口)到socket套接字, 在AF_INET下,以元组(host,port)的形式表示地址。服务器

s.bind(('xxx.xxx.xxx.xxx',port))

s.listen()

开始TCP监听。backlog指定在拒绝链接以前,操做系统能够挂起的最大链接数量。该值至少为1,大部分应用程序设为5就能够了。socket

ps:udp不支持listen()tcp

s.listen(5)

s.accept()

被动接受TCP客户端链接,(阻塞式)等待链接的到来函数

ps: udp不支持大数据

conn,addr = s.accept()

关于accept()返回值在官方文档是这么说的this

The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection.

有两个返回值conn和address,第一个返回值为新的 socket 对象可用于发送和接受数据,形式大体以下操作系统

<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.124.141', 12345), raddr=('192.168.124.1', 15563)>

address为一个元组,元组包含远端链接的ip地址和端口,形如

('192.168.124.1', 15563)

客户端套接字

s.connect()

主动初始化TCP服务器链接。通常address的格式为元组(主机/ip,port),若是链接出错,返回socket.error错误。

s.connect(('192.168.124.1',22222))

s.connect_ex()

connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

公共用途的套接字函数

s.recv()

socket.recv(bufsize[, flags])

从套接字接收数据。返回值是表示接收到的数据的bytes对象。bufsize指定一次接收的最大数据量。通常为1024

s.recv(1024)

s.send()

发送数据,将数据发送到socket套接字。(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)

s.send('This is Socket Client!'.encode('utf-8'))

s.sendall()

发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)

s.close()

关闭socket 套接字

简单例子 TCP链接

SocketServer.py

#!/usr/bin/python3
#-*- coding:UTF-8 -*-

import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
phone.bind(('192.168.124.141',12345)) 

phone.listen(5) 

conn,addr=phone.accept() 
print(conn,addr)
print('Remote IP Address is',addr)

client_msg=conn.recv(1024) 
print('client msg: %s' %client_msg)
conn.send(client_msg。upper()) 

conn.close()
s.close()

SocketClient.py

import socket

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

s.connect(('192.168.124.141', 12345))

s.send('this is socket client!'.encode('utf-8'))

res_msg = s.recv(1024)
print(res_msg)

s.close

服务端

image-20201124233020283

客户端

image-20201124233105709

简单例子UDP链接

SocketServer.py

#!/usr/bin/python3
#-*- coding:UTF-8 -*-

import socket


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

ip = '192.168.124.141'
port = 12346

s.bind((ip,port))

recv_data,addr = s.recvfrom(1024)
print('Client Send Message: %s' %recv_data)

server_send_data = 'this is server!!!'

s.sendto(server_send_data.encode(),addr)

s.close()

SocketClient.py

import socket


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

s.sendto('this is socket client!!!'.encode('utf-8'),('192.168.124.141',12346))

res_msg,addr = s.recvfrom(1024)

print(res_msg)

s.close()

服务端

image-20201125001423390

客户端

image-20201125001439186

相关文章
相关标签/搜索