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. struct ifreq 获取IP 和mac和修改mac

    2012-09-11 14:26 struct ifreq 获取IP 和mac和修改mac 配置ip地址和mask地址: ifconfig eth0 192.168.50.22  netmask 25 ...

  2. 算法习题---4.3救济金发放(UVa133)

    一:题目 (n< )个人站成一圈,逆时针编号为1~n.有两个官员,A从1开始逆时针数,B从n开始顺时针数.在每一轮中,官员A数k个就停下来,官员B数m个就停下来(注意有可能两个官员停在同一个人上 ...

  3. Linux -- Proactor(及其与Reactor的比较)

    高并发服务器常由多线程+IO复用服务器(one event loop per thread) 两种I/O多路复用模式:Reactor和Proactor 一般地,I/O多路复用机制都依赖于一个事件多路分 ...

  4. MGR集群搭建

    MGR全称MySQL Group Replication(Mysql组复制),是MySQL官方于2016年12月推出的一个全新的高可用与高扩展的解决方案.MGR提供了高可用.高扩展.高可靠的MySQL ...

  5. PAT 甲级 1048 Find Coins (25 分)(较简单,开个数组记录一下即可)

    1048 Find Coins (25 分)   Eva loves to collect coins from all over the universe, including some other ...

  6. LeetCode_121. Best Time to Buy and Sell Stock

    121. Best Time to Buy and Sell Stock Easy Say you have an array for which the ith element is the pri ...

  7. laravel php门面模式

    门面模式   理解3个概念: 1)Container的概念,laravel所有的服务都注册在container里面,至于如何注册,就是使用service provider   2)service pr ...

  8. Node express post 大小设置

    body-parser 默认限制了body长度 var bodyParser = require('body-parser'); app.use(bodyParser.json({"limi ...

  9. 动态规划算法(Dynamic Programming,简称 DP)

    动态规划算法(Dynamic Programming,简称 DP) 浅谈动态规划 动态规划算法(Dynamic Programming,简称 DP)似乎是一种很高深莫测的算法,你会在一些面试或算法书籍 ...

  10. Mac OS X下把 /etc/sudoers 写错了怎么办?(转载https://blog.csdn.net/robertsong2004/article/details/53725285)

    重要的事情先说一下,首先为了回避这个问题,一定要用 visudo 来改 /etc/sudoers 文件. 问题描述: 1. 用  sudo vi 直接改 /etc/sudoers 并覆盖原文件. 2. ...