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基本用法的更多相关文章

  1. Java中的Socket的用法

                                   Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...

  2. Java语言Socket接口用法详解

    Socket接口用法详解   在Java中,基于TCP协议实现网络通信的类有两个,在客户端的Socket类和在服务器端的ServerSocket类,ServerSocket类的功能是建立一个Serve ...

  3. 第一篇 网站基础知识 第4章 Java中Socket的用法

    第4章 Java中Socket的用法 4.1 普通Socket的用法 Java中的网络通信是通过Socket实现的,Socket分为ServetSocket和Socket两大类,ServetSocke ...

  4. 2015-12-27 socket的用法

    sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0) sk.bind(address) s.bind(address) 将套接字绑定到地址.a ...

  5. JAVA中Socket的用法模拟服务端和客户端

    <看透springMvc源代码分析与实践>学习笔记 Socket分为ServerSocket和Socket两个大类 ServerSocket用于服务端,可以通过accept方法监听请求,监 ...

  6. 通过编写聊天程序来熟悉python中多线程及socket的用法

    1.引言 Python中提供了丰富的开源库,方便开发者快速就搭建好自己所需要的应用程序.本文通过编写基于tcp/ip协议的通信程序来熟悉python中socket以及多线程的使用. 2.python中 ...

  7. setsockopt 设置socket 详细用法

    1.closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:BOOL bReuseaddr=TRUE;setsockopt(s,SOL_SOCKET ,SO ...

  8. 【android】Socket简单用法

    Socket通常也称做”套接字“,用于描述IP地址和端口,废话不多说,它就是网络通信过程中端点的抽象表示.值得一提的是,Java在包java.net中提供了两个类Socket和ServerSocket ...

  9. setsockopt 设置socket 详细用法(转载)

    转自:http://www.cppblog.com/killsound/archive/2009/01/16/72138.html 1.closesocket(一般不会立即关闭而经历TIME_WAIT ...

随机推荐

  1. ISO/IEC 9899:2011 条款5——5.2.3 信号与中断

    5.2.3 信号与中断 1.函数应该被设计为它们可以被一个信号在任一时刻打断,或是被一个信号处理所调用,或是两者都发生,对于初期不发生改变,但仍然处于活动状态,调用的控制流(在中断之后),函数返回值, ...

  2. Chrome浏览器控制网速的方法

  3. python学习:python的常用功能示例2

    1. python 写入txt with open("douban.txt","w") as f: f.write("这是个测试!") fi ...

  4. LeetCode_101. Symmetric Tree

    101. Symmetric Tree Easy Given a binary tree, check whether it is a mirror of itself (ie, symmetric ...

  5. Mac PhpStorm 2017 破解

    官网下载链接: https://www.jetbrains.com/zh/phpstorm/specials/phpstorm/phpstorm.html?utm_source=baidu&u ...

  6. python使用退格键时出现^H解决方法

    Linux 使用退格键时出现^H解决方法 1.临时解决 按ctrl 2.永久解决 基本现象 进入 Python shell,按下 Delete/Backspace 键: Python 3.5.2 (d ...

  7. css3实现左右锯齿效果

    要实现的效果:css3实现左右锯齿效果 <!DOCTYPE html> <html> <head> <meta charset=" utf-8&qu ...

  8. jira使用一:如何给项目分组、sprint并行、禁止发送消息给atlassian

    问题一:如何设置多个sprint并行? 问题二: 如何分组显示 设置泳道,并快速过滤 问题3:添加所属产品? 管理员登录Jira后台设置-问题-自定义字段找到:所属产品,进入 配置 界面在配置界面中, ...

  9. 20175316盛茂淞 2018-2019-2 《Java程序设计》第10周学习总结

    教材知识总结 第12章 Java多线程机制 进程与线程 进程是程序的一次动态执行进程,它对应了从代码加载.执行至执行完毕的一个完整过程 线程不是进程,一个进程在其执行过程中,会产生多个线程,线程间可以 ...

  10. ROS下gazebo打开出现问题

    通常情况下,在装完ros后,打开gazebo, 会出现无法连接服务器获取模型的情况.这样,我们打开gazebo, 终端会提示timeout,gazebo界面没有网格. 这是因为服务器网站地址好像已经换 ...