socket基本用法
socket介绍
1、什么是socket
socket是应用层与传输层中间的一个软件抽象层,它是一组接口。它把TCP/IP这些复杂的协议统一封装起来
这样我们只要知道如何使用socket就好,就已经符合了传输层往下的一大串协议
2、为什么要使用socket
如果没有socket而我们写的代码又要让别人能正确解析,就需要一层层往下研究协议,写出符合协议的代码
而我们大家传输层往下的代码基本一样,所以把这些代码封装成一个模块,方便大家使用,不用去考虑传输层
以下的东西
3、socket发展
套接字起源于20世纪70年代,一开始,套接字被设计用在同一台主机上多个应用程序的通讯,这也被称为
进程间通讯或者IPC。后来网络发展,又被应用于网络协议上。
套接字有两种(或者称为有两个种族):
基于文件类型的套接字家族:名字 --> AF_UNIX
基于网络类型的套接字家族:名字 --> AF_INET被用于ipv4 AF_INET6被用于ipv6
socket用法
# 需要明确的是:
关于网络协议和socket相关概念,对于所有编程语言都是一致的,区别仅仅是个编程语言的函数名称不同
1、服务器端
import socket
# 获得socket对象 AF_INET表示基于网络的套接字
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# SOCK_STREAM表示的是TCP协议 SOCK_DGRAM表示的是UDP协议
# 将socket对象绑定ip地址和端口号
sk.bind(('127.0.0.1',8080)) # 参数需要传入一个元组
# 相当于电话的开机 括号里的参数表示可以同时接收5个请求
sk.listen(5) # 一般服务器都不需要关闭,所以加个while循环
while True:
# 进入监听状态,等待别人链接过来,有两个返回值,一个是对方的socket对象,一个是对方的ip以及端口
client,addr = sk.accept()
# 收发消息一般都需要多次循环发送,也加个while循环
while True:
try: # 如果对面强行关闭,为了程序不崩,就需要异常处理
msg = client.recv(1024) # recv表示接收,括号里是最大接收字节
if not msg: # 如果接收到的消息是空字符串,就表示对面正常退出,需要打断循环
break
# send表示发送数据,发送的数据必须是二进制数据
client.send('二进制数据'.encode('utf-8'))
except Exception as e:
print(e)
break
client.close() # 关闭对面传过来的对象
sk.close() # 关闭服务器的socket对象
2、客户端
import socket
# 获取socket对象,括号里默认是AF_INET 和 SOCK_STREAM 所以可以不写
sk = socket.socket()
# 链接到服务器端 括号里也是一个元组,包含ip地址以及对方的端口号
sk.connect(('127.0.0.1',8080)) # 自己的端口号系统会随机分配,不需要设置 while True: # 收发信息也需要循环
try: # 为了防止服务器非正常下线而导致客户端直接崩溃,需要加入异常处理
cmd = input('>>(q:退出)')
if cmd == 'q': # 给客户端一个可以正常退出的方法
break
if not cmd: # 如果直接敲回车,那么cmd就是空字符串,TCP协议对此进行优化
continue # 正常收发消息过程中,你传入空字符串,它不会帮你发送
sk.send(cmd.encode('utf-8'))
# 如果上面没有做空判断,输入空会直接跳过send这步,这样客户端和服务器端都处于接收状态,卡住不动
sk.recv(1024)
except Exception as e:
print(e)
break
sk.close() # 关闭socket对象
3、基于TCP的socket通讯流程图
socket常见问题
1、端口占用
报错信息
Traceback (most recent call last):
File "F:/pyprogram/day31/homework/topic2/test.py", line 6, in <module>
sk.bind(('127.0.0.1',8080))
OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。
问题发生的原因
1.可能是由于你已经启动了服务器程序,却又再次启动了服务器程序,同一个端口不能被多个进程使用导致
2.三次握手或四次挥手时,发生了异常导致对方程序已经结束而服务器任然处于time_wait状态导致
3.在高并发的场景下,由于连接的客户端太多,也会产生大量处于time_wait状态连接
解决的方案
第一种重新选择端口后就可以,或者把之前的占用端口的进程关闭掉
第二三种以后再说
2、强行关闭链接
报错信息
Traceback (most recent call last):
File "F:/pyprogram/day31/part2/客户端.py", line 12, in <module>
client.send(msg.encode('utf-8'))
ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。
问题发生的原因
当客户端与服务器链接成功后,如果一方没有执行close,而是直接强行终止程序(或是遇到异常被迫终止)
都会导致另一方发生问题
在windows下,接收数据的一方在recv函数处将抛出异常
解决的方案
用try...except语法抓取异常,抓到对方强退异常后并处理
3、客户端正常结束,服务器端无限循环空字符
报错信息
不会产生报错信息,但是服务器端会一直循环空字符串
问题发生的原因
客户端正常close()之后,会给服务器发送一个空字符串,
如果服务器端没有发送数据的话,就会一直循环接收这个空字符串,占用CPU资源
解决的方案
在服务器端接收的地方加上空字符串判断,如果是空字符串,就表示对方客户端退出了
那么判断空成功,让自己也退出循环
socket基本用法的更多相关文章
- Java中的Socket的用法
Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...
- Java语言Socket接口用法详解
Socket接口用法详解 在Java中,基于TCP协议实现网络通信的类有两个,在客户端的Socket类和在服务器端的ServerSocket类,ServerSocket类的功能是建立一个Serve ...
- 第一篇 网站基础知识 第4章 Java中Socket的用法
第4章 Java中Socket的用法 4.1 普通Socket的用法 Java中的网络通信是通过Socket实现的,Socket分为ServetSocket和Socket两大类,ServetSocke ...
- 2015-12-27 socket的用法
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0) sk.bind(address) s.bind(address) 将套接字绑定到地址.a ...
- JAVA中Socket的用法模拟服务端和客户端
<看透springMvc源代码分析与实践>学习笔记 Socket分为ServerSocket和Socket两个大类 ServerSocket用于服务端,可以通过accept方法监听请求,监 ...
- 通过编写聊天程序来熟悉python中多线程及socket的用法
1.引言 Python中提供了丰富的开源库,方便开发者快速就搭建好自己所需要的应用程序.本文通过编写基于tcp/ip协议的通信程序来熟悉python中socket以及多线程的使用. 2.python中 ...
- setsockopt 设置socket 详细用法
1.closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:BOOL bReuseaddr=TRUE;setsockopt(s,SOL_SOCKET ,SO ...
- 【android】Socket简单用法
Socket通常也称做”套接字“,用于描述IP地址和端口,废话不多说,它就是网络通信过程中端点的抽象表示.值得一提的是,Java在包java.net中提供了两个类Socket和ServerSocket ...
- setsockopt 设置socket 详细用法(转载)
转自:http://www.cppblog.com/killsound/archive/2009/01/16/72138.html 1.closesocket(一般不会立即关闭而经历TIME_WAIT ...
随机推荐
- 【转载】 一文看懂深度学习新王者「AutoML」:是什么、怎么用、未来如何发展?
原文地址: http://www.sohu.com/a/249973402_610300 原作:George Seif 夏乙 安妮 编译整理 ============================= ...
- 阶段5 3.微服务项目【学成在线】_day18 用户授权_12-前端集成认证授权-携带JWT授权
携带JWT授权 登陆后jwt已经存到了sessionStorage里面 当进行微服务的请求就要携带令牌.我们在拦截器里面做文章. 在axios的intercepters拦截器上 手工的给这个课程 造一 ...
- Swift学习 (四)
5.枚举与结构体: 不必给枚举成员提供一个值.如果我们想要为枚举成员提供一个值(raw value),我们可以用字符串,字符,整型或浮点数类型. 1 2 3 4 5 6 7 enum CompassP ...
- pcntl_waitpid函数解释
pcntl_waitpid 等待或返回fork的子进程状态.多进程的主进程创建了子进程,那主进程如何确认子进程的状态呢. 假如主进程需要根据子进程的状态做不同的处理呢, 这里的状态包括子进程被kill ...
- 【opencv】split
opencv-split Divides a multi-channel array into several single-channel arrays. code ,,,,,,,,,,,}; Ma ...
- Python3之切片及内置切片函数slice
切片 取一个list或tuple的部分元素是非常常见的操作.比如,一个list L=[0,1,2,3,4,5,6,7,8,9] 取前3个元素,应该怎么做 笨方法,一个个列出来 >> ...
- (IStool)64位软件安装在32位操作系统时给出提示
需求:64位的软件当在32位操作系统下安装时,需要提示用户不能在32位操作系统中进行安装 实现:打包时启用64位模式(打包工具用的是Inno Setup 5) 安装脚本段需要添加以下代码: [Setu ...
- JS选中和取消选中checkbox
document.getElementsByTagName("input")[0].checked = 0;//不选择 document.getElementsByTagName( ...
- [转帖]详解shell脚本括号区别--$()、$「 」、$「 」 、$(()) 、「 」 、「[ 」]
详解shell脚本括号区别--$().$「 」.$「 」 .$(()) .「 」 .「[ 」] 原创 波波说运维 2019-07-31 00:01:00 https://www.toutiao.com ...
- oracle 列合并成并用拼接符拼接 -- LISTAGG函数用法
==注:wm_concat(str1) 11g 后不支持使用== LISTAGG函数用法 select LISTAGG(name, ',') WITHIN GROUP (ORDER BY id) fr ...