TCP : 可靠传输,不安全,UDP: 安全传输,不可靠
一台机器上有2^16-1=65535个端口(1-1024)保留自己开就1024往上
socket (套接字):也可以理解为它是一个管道,用于描述IP地址和端口
socket是一种特殊的文件:针对服务器端和客户端来 打开(建立链接),读(发送数据),写(接收数据)关闭的模式来实现信息的交换
一、socket函数
socket.socket(family,type[, protocol]) 默认协议为TCP/IP
# socket.slcketpair([family,type[,proto]]]):
# socket.create_connection(address[,timeout[, source_address]])
参数说明:
1.family指定应用程序使用的通信协议的协议族
family参数 | |
socket.AF_UNIX | 只能单一的在Unix系统进行进程通信,一种本地的管道(socket) |
socket.AF_INET | IPv4 为TCP/IP协议的默认值,服务器之间的网络通信 |
socket.AF_INET6 | IPv6 |
2.type创建套接字的类型
type参数 | |
socket.SOCK_STREAM | 流式socket,用于TCP时选用 |
socket.SOCK_DGRAM | 数据报式socket,用于UDP时选用 |
socket.SOCK_RAM |
原始套接字,普通的套接字无法处理ICMP , IGMP 等网络报文,而SOCK_RAM可以;其次,SOCK_RAM也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCT套接字选项由用户构造IP头。 |
socket.SOCK_RDM |
是一种可靠的UDP形式,即可保证交付数据但不保证顺序 ,SOCK_RAM用来提供对原始协议的低级访问,在需要某些特殊操作时使用,如发生ICMP报文,SOCK_RAM通常仅限于高级用户或管理员运行的程序使用. |
3.protocol指明所要接收的协议类型,通常设置为0,系统就会根据地址格式和套接类别自动选择一个合适的协议
protocol参数 | |
socket.IPPROTO_TAW |
相当于protocol=255,此时socket只能用来发送IP包,而不能接收任何的数据,发送的数据需要自己填充IP包头,并且自己计算校验和 |
socket.IPPROTO_IP |
相当于protocol=0,此时用于接收任何的IP数据包,其中校验和和协议分析由系统完成 |
二、socket内建方法
服务器端套接字 | |
sk.bind() |
将套接字绑定地址,address地址的格式取决于地址簇,在AF_INET下,以(host.port )的形式表示地址 |
sk.listen(backlog) |
开始监听传入连接,backlog指定在拒绝连接之前,可以挂起的最大连接数量,等待排队的最多排几个,如:backlog等于5,表示内核已经接到了连接要求,但服务器还没有调用accept进行处理的连接个数,这个值不能无限大,因为要在内核中维护连接队列。 |
sk.accept() |
接受TCP客户连接并返回(conn,address),阻塞式等待连接其到来,其中conn是新的套接字对象,可以用来接受和发送数据,address 是客户端的地址。 |
客户端套接字 | |
s.connect() | 主动初始化TCP服务器连接,一般address的格式为元组(hostname,port),如果连接出错,则返回socket.error错误 |
s.connet_ex() | 同上,不过,连接成功是返回0,连接失败是返回错误码,不会抛出异常 |
公共用途套接字 | |
sk.recv(bufsize[,flag]) |
接受套接字的数据。数据以字符串的形式返回,bufsize指定最多可接收的数据(一般为8192),flag提供有关消息的其他信息,通常可以忽略 |
sk.recvform() | 与recv()类似,多用于接受UDP数据,返回值为(data,address),其中data是包含接受数据的字符串,address是发送数据的套接字地址 |
sk.send() | 发送套接字数据,将string中的数据发送到连接的套接字,返回值是要发送的字节数量,该数据可能小于string的字节大小 |
sk.sendall() | 完整发送TCP数据,将string中的数据发送到连接的套接字,但返回之前会尝试一次性发送,就是不断的调用send,发送成功返回None,失败则抛出异常 |
sk.sendto() | 发送UDP数据,将数据发送到套接字,address的形式是(ipaddr,port)的元组,指定远程地址,返回值是发送的字节数 |
sk.close() | 关闭套接字 |
sk.getpeername() | 返回连接套接字的远程地址,返回值通常是元组(ipaddr,port) |
sk.getsockname() | 返回套接字自己的地址,通常是一个元组(ipaddr,port) |
sk.setsockopt() | 设置给定套接字选项的值 |
sk.getsockopt() | 返回条件字选项的值 |
sk.settimeout(timeout) | 设置套接字操作的超时期,timeout是一个浮点数,单位为秒,值为None表示没有超时期,一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect()) |
sk.gettimeout() | 返回当前超时期的值,如果没有设置超时期,则返回为None |
sk.fileno() | 返回套接字的文件描述符 |
sk.setblocking(flag) | 是否阻塞(默认为True),如果设置False或0(即非堵塞模式),那么accept和recv时一旦无数据,则报错 |
sk.makefile() | 创建一个与该套接字相关联的文件 |
实例一:你说一句,我说一句
import socket
ip_port = ("127.0.0.1", 1313) sk = socket.socket()
sk.bind(ip_port) # 创建端口
sk.listen(5) # 监听多少个 while True:
print("等待消息。。")
conn,addr = sk.accept() # 生成地址和一个实例线程
while True:
try: # 如果客户端端口,没有消息了,抓取异常,跳出循环
client_data = conn.recv(1024) # 接收消息
print(str(client_data, "utf8"))
except Exception:
print("over")
break server_input = input(">>").strip() # 发送消息
conn.sendall(bytes(server_input,"utf8"))
conn.close()
服务器端
import socket ip_port = ("127.0.0.1",1313) sk = socket.socket() # 实例化
sk.connect(ip_port) # 连接端口
while True:
client_data = input(">>").strip()
sk.sendall(bytes(client_data,"utf8")) # 发送消息
server_data = sk.recv(1024) # 接收消息
print(str(server_data,"utf8"))
sk.close()
客户端
实例二:在Linux上Python3实现客户端发命令,服务器端把客户端命令实现,并发回客户端
#!/usr/bin/python
# -*- coding:utf-8 -*-
import socket
import subprocess
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)
while True:
print('server waiting...')
conn,addr = sk.accept()
while True:
client_data = conn.recv(1024)
if not client_data:break # 如果没有客户端发来的消息则退出
print('recv cmd:',str(client_data,'utf8')) # 打印客户端发来了的消息
cmd = str(client_data, 'utf8').strip() cmd_call = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) # 把客户发来的消息执行结果放在管道里 cmd_result = cmd_call.stdout.read() # 把 cmd 的执行结果读出来
if len(cmd_result) == 0: # 如果结果为 0
cmd_result = b'cmd execution has no output...'
ack_msg = bytes('CMD_RESULT_SIZE|%s' % len(cmd_result), 'utf8') # 文件名和长度发回客户端
conn.send(ack_msg)
client_ack = conn.recv(50) # 向客户端确认消息 (收),用来解决粘包
if client_ack.decode() == "yes":
conn.send(cmd_result) # 确认后,才向客户端发数据
conn.close()
服务器端
#!usr/bin/python3
# -*- coding:utf-8 -*-
import socket ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.connect(ip_port) while True:
user_input = input('cmd:').strip()
if len(user_input) == 0:continue
if user_input =='q':break # 按q可以退出 sk.send(bytes(user_input,'utf8')) # 发消息 server_ack_msg = sk.recv(100) # 每次接收服务器端发来的消息最大长度
cmd_res_msg = str(server_ack_msg.decode()).split("|") # 去掉 | ,并转码
print('server response:',cmd_res_msg) # 打印 文件名,总长度
if cmd_res_msg[0] =="CMD_RESULT_SIZE": # 确定 文件名
cmd_res_size = int(cmd_res_msg[1]) # 确定文件长度
sk.send(b"yes") # 发回消息确认,解决粘包 res = '' # 保存 文件内容
received_size = 0
# (在服务器端和客户端中各有一个缓冲区,在一定的时间内客户端接收数据不够500,也会先进行收数据,其他的就下次再收)
while received_size < cmd_res_size: # 如果 文件内容,小于发来的长度
data = sk.recv(500) # 每次接收最大长度 为500 received_size += len(data) # 累加
res += str(data.decode())
else:
print(str(res))
print('---------------------')
sk.close()
客户端
客户端: [root@localhost python_day2018_10_28]# python3 client_1.py
cmd:df
server response: ['CMD_RESULT_SIZE', '']
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/centos-root 18307072 2056032 16251040 12% /
devtmpfs 490096 0 490096 0% /dev
tmpfs 500664 0 500664 0% /dev/shm
tmpfs 500664 6956 493708 2% /run
tmpfs 500664 0 500664 0% /sys/fs/cgroup
/dev/sda1 508588 111880 396708 22% /boot
tmpfs 100136 0 100136 0% /run/user/0 ---------------------
cmd: 服务器端: [root@localhost python_day2018_10_28]# python3 server.py
server waiting...
recv cmd: df
result
Python_socket的更多相关文章
-
Python_socket常见的方法、网络编程的安全注意事项、socketsever模块、浏览器中在一段时间记录用户的登录验证机制
1.socket常见的方法 socket_常见方法_服务器端 import socket from socket import SOL_SOCKET,SO_REUSEADDR sk = socket. ...
-
python_socket (套接字)
socket是计算机网络通信的基本的技术之一.如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的. 网络上两个程序通过一个双向的通信连接实现数据的交换,这个连接 ...
-
python_socket登陆验证_明文
client.py import socket import struct sk=socket.socket() sk.connect(('127.0.0.1',9005)) while True: ...
-
使用 Python 进行 socket 编程
本文主要参考 https://docs.python.org/3/howto/sockets.html . 本文只讨论 STREAME(比如 TCP) INET(比如 IPv4) socket. 在多 ...
-
python开发之路目录
Python 目录 基础 python入门 python数据类型.字符编码.文件处理 python函数基础 python函数进阶 python装饰器函数 python装饰器函数 python递归函数 ...
-
python_18(Django基础)
第1章 web框架的本质 1.1 socket 1.2 空格后面是主体内容 1.3 HTTP协议 1.3.1 响应流程 1.4 HTTP请求方法 1.5 HTTP工作原理 1.6 URL 1.7 HT ...
随机推荐
-
codeforces 446C DZY Loves Fibonacci Numbers 线段树
假如F[1] = a, F[2] = B, F[n] = F[n - 1] + F[n - 2]. 写成矩阵表示形式可以很快发现F[n] = f[n - 1] * b + f[n - 2] * a. ...
-
FireDAC如何连接ORACLE数据库
UniDac对Oracle的Direct连接,不需要安装Oracle客户端dll,deploy时真的是方便又快捷. FireDac连接Oracle,在没有Oracle Client的情况下,是可以连接 ...
-
chmod chgrp chown
Linux系统中的每个文件和目录都有访问许可权限,用它来确定谁可以通过何种方式对文件和目录进行访问和操作. 文件或目录的访问权限分为只读,只写和可执行三种.以文件为例,只读权限表示只允许读其内容,而禁 ...
-
mysql出现的错误
(一)ERROR 1005 (HY000): Can't create table '.\day19\user_role.frm' (errno: 121) 今天遇到的这个问题是因为创建了五张表,其中 ...
-
IIS 7.0 Features and Vista Editions
原文 IIS 7.0 Features and Vista Editions Overview of IIS 7.0 differences Across Windows Vista Editions ...
-
关于easyui的datagrid属性出现乱码问题
今天遇到这个问题也是纠结了好久,经过在网上各种查询总结,得出以下经验: 1:网页字符集设置为UTF-8: <meta content="charset=UTF-8 " /&g ...
-
AI 新技术革命将如何重塑就业和全球化格局?深度解读 UN 报告(上篇)
欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 张钦坤 腾讯研究院秘书长蔡雄山 腾讯研究院法律研究中心副主任祝林华 腾讯研究院法律研究中心助理研究员曹建峰 腾讯研究院法律研究中心高级研究员 ...
-
asp.net MVC路由配置总结
URL构造 命名参数规范+匿名对象 routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}&qu ...
-
Vue小项目二手书商城:(一)准备工作、组件和路由
本项目基于vue2.5.2,与低版本部分不同之处会在(五)参考资料中提出 完整程序:https://github.com/M-M-Monica/bukesi 实现内容: 资源准备(mock数据) 组件 ...
-
30-socketserver类
SocketServer模块简化了编写网络服务程序的任务.同时SocketServer模块也是Python标准库中很多服务器框架的基础. socketserver模块可以简化网络服务器的编写,Pyth ...