首页 > 其他分享 >C /S 架构——socke模块

C /S 架构——socke模块

时间:2022-11-16 18:46:42浏览次数:40  
标签:架构 socket server client 模块 socke utf 接字 服务端

C /S 架构——socke模块

一、socket概念

如果我们需要编写基于网络进行数据交互的程序 意味着我们需要自己通过代码来控制我们之前所学习的OSI七层(很繁琐 很复杂 类似于我们自己编写操作系统)
socket类似于操作系统 封装了丑陋复杂的接口提供简单快捷的接口

socket也叫套接字
	基于文件类型的套接字家族(单机)
  	AF_UNIX
  基于网络类型的套接字家族(联网)
  	AF_INET

1.Socket通信

ocket是应用层与TCP/IP协议簇通信的中间抽象层,是一组接口。在设计模式中其实就是门面模式。Socket将复杂的TCP/IP协议簇隐藏在接口后面,对于用户而言,一组接口即可让Socket去组织数据,以符合指定的协议。

socket 其实就是操作系统提供给程序员操作「网络协议栈」的接口,说人话就是,你能通过socket 的接口,来控制协议找工作,从而实现网络通信,达到跨主机通信。

2.关于套接字socket

	所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议栈进行交互的接口
    
    套接字是通信的基石,是支持TCP/IP协议的路通信的基本操作单元。可以将套接字看作不同主机间的进程进行双间通信的端点,它构成了单个主机内及整个网络间的编程界面。套接字存在于通信域中,通信域是为了处理一般的线程通过套接字通信而引进的一种抽象概念。套接字通常和同一个域中的套接字交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序),各种进程使用这个相同的域互相之间用Internet协议簇来进行通信。
    
	Socket(套接字)可以看成是两个网络应用程序进行通信时,各自通信连接中的端点,这是一个逻辑上的概念。它是网络环境中进程间通信的API(应用程序编程接口),也是可以被命名和寻址的通信端点,使用中的每一个套接字都有其类型和一个与之相连进程。通信时其中一个网络应用程序将要传输的一段信息写入它所在主机的 Socket中,该 Socket通过与网络接口卡(NIC)相连的传输介质将这段信息送到另外一台主机的 Socket中,使对方能够接收到这段信息。 Socket是由IP地址和端口结合的,提供向应用层进程传送数据包的机制

二、socket代码简介

1.server端

# coding:utf-8

# 导入socket模块
import socket

# 1、产生一个socket对象并指定采用的通信版本喝协议(TCP)
# 括号内不屑参数,默认就是TCP协议、family = AF_INET基于网络的套接字
# type = SOCK_STREAM流式协议即TCP
server = socket.socket()

# 2、绑定一个固定的地址(服务器必备的条件)
# 127.0.0.1为本地回环地址,只有自己的电脑可以访问
# 括号内前面为IP地址、后面为端口号
server.bind(('127.0.0.1', 8080))

# 3、建立半连接池(就是可以规定最大的连接数为多少)
server.listen(8)

# 4、等待接收客户端的数据、地址
# sock双向通道,addr客户端的地址
# return scok、addr 三次握手
sock, addr = server.accept()

# 5、接收客户端发来的数据 括号内表示接收的字节数
date = sock.recv(1024)

# 5.1、对接收来的数据进行解码并输出
print(date.decode('utf-8'))

# 5.2、给客户端发送消息 注意消息必须是bytes类型
sock.send('you are right! i follow you! '.encode('utf-8'))

# 6.关闭双向通道
sock.close()

# 7.关闭服务器
server.close()


2.client端

# coding:utf-8
# 导入socket模块
import socket

# 1.生成socket对象指定类型和协议
client = socket.socket()

# 2.通过服务端的地址链接服务器
client.connect(('127.0.0.1', 8080))

# 3.直接给服务端发送消息
client.send('i have very much money!come on baby!'.encode('utf-8'))

# 4. 接收服务器端发来的消息
data = client.recv(1024)
print(data.decode('utf-8'))

# 5.断开与服务端的链接
client.close()

三、代码优化

1.聊天内容自定义
	针对消息采用input获取
2.让聊天循环起来
	将聊天的部分用循环包起来
3.用户输入的消息不能为空
	本质其实是两边不能都是recv或者send 一定是一方收一方发 
4.服务端多次重启可能会报错
	Address already in use 主要是mac电脑会报
  	方式1:改端口号
  	方式2:博客里面代码拷贝即可
5.当客户端异常断开的情况下 如何让服务端继续服务其他客人
	windows服务端会直接报错
  mac服务端会有一段时间反复接收空消息延迟报错	
  	异常处理、空消息判断

1.server端

# coding:utf-8

# 导入socket模块
import socket

# 导入
from socket import SO_REUSEADDR, SOL_SOCKET

# 1、产生一个socket对象并指定采用的通信版本喝协议(TCP)
# 括号内不屑参数,默认就是TCP协议、family = AF_INET基于网络的套接字
# type = SOCK_STREAM流式协议即TCP
server = socket.socket()
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)

# 2、绑定一个固定的地址(服务器必备的条件)
# 127.0.0.1为本地回环地址,只有自己的电脑可以访问
# 括号内前面为IP地址、后面为端口号
server.bind(('127.0.0.1', 8080))

# 3、建立半连接池(就是可以规定最大的连接数为多少)
server.listen(8)


while True:

    # 4、等待接收客户端的数据、地址
    # sock双向通道,addr客户端的地址
    # return scok、addr 三次握手
    try:
        sock, addr = server.accept()
    except OSError:
        break
    while True:
        try:
            # 5、接收客户端发来的数据 括号内表示接收的字节数
            date = sock.recv(1024)

            # 5.1、对接收来的数据进行解码并输出
            print(date.decode('utf-8'))

            # 5.2、给客户端发送消息 注意消息必须是bytes类型
            msg = input('please input you need sent client message>>>:')
            try:
                if msg == 'q':

                    # 6.关闭双向通道
                    sock.close()

                    # 7.关闭服务器
                    server.close()
            except OSError:
                break
            sock.send(msg.encode('utf-8'))
        except OSError:
            break

2.client端

# coding:utf-8
# 导入socket模块
import socket

# 1.生成socket对象指定类型和协议
client = socket.socket()

# 2.通过服务端的地址链接服务器
client.connect(('127.0.0.1', 8080))

while True:
    # 3.直接给服务端发送消息
    msg = input('please input you need sent server message>>>:')
    try:
        if msg == 'q':
            # 5.断开与服务端的链接
            client.close()
        client.send(msg.encode('utf-8'))
    except OSError:
        break



    # 4. 接收服务器端发来的消息
    data = client.recv(1024)
    print(data.decode('utf-8'))

四、报错处理

报错信息:
[WinError 10061] 由于目标计算机积极拒绝,无法连接。

解决办法:
1.按住开始键+r,输入regedit,打开注册表
2.然后在计算\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings下面找到ProxyEnable将十六进制的值改为1


解决问题
TypeError: a bytes-like object is required, not 'str'
解决思路
问题出在python3.5和Python2.7在套接字返回值解码上有区别:
python bytes和str两种类型可以通过函数encode()和decode()相互转换,
str→bytes:encode()方法。str通过encode()方法可以转换为bytes。
bytes→str:decode()方法。如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法。


TCP端口复用引发的异常,用setsockopt来解决

我们在并发连接一个服务端时候他会出现这种情况

OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。假如端口被socket使用过,并且利用socket.close()来关闭连接,但此时端口还没有释放,要经过一个TIME_WAIT的过程之后才能使用,这是TNN的相当烦银的,为了实现端口的马上复用,可以选择setsockopt()函数来达到.端口复用的实现,我在这里用Python举个TCP端口复用的例子,UDP套接字要做的完全一样。我们可以在定义好的端口加这句

from socket import 

server = socket()

server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)

server.bind(('127.0.0.1', 8000))

server.listen(5)

五、半连接池的概念

server.listen(5)  # 半连接池

当有多个客户端来链接的情况下 我们可以设置等待数量(不考虑并发问题)
假设服务端只有一个人的情况下

在测试半连接池的时候 可以不用input获取消息 直接把消息写死即可 

标签:架构,socket,server,client,模块,socke,utf,接字,服务端
From: https://www.cnblogs.com/HaiMan/p/16897099.html

相关文章

  • OSI七层协议补充与socket套节字
    OSI七层协议补充与socket套节字一、传输层之TCP与UDP协议TCP与UDP协议都是用来规定通信方式的,数据传输过程中能够遵循的协议有很多其中TCP协议和UDP协议是较为常见的两......
  • Python实验报告——第8章 模块
    Python实验报告——第8章模块 实验报告【实验目的】 1.掌握Python内置的标准模块和第三方模块的使用。【实验条件】1.PC机或者远程编程环境。 【实验内容......
  • python JSON模块
    一、JSON介绍JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,易于人阅读和编写。二、常用方法方法描述json.loads()将JSON字符串转化为Python对......
  • 构造Socket
    1:Socket的构造函数​​Socket​​()​​Socket​​(​​InetAddress​​ address,int port)​​Socket​​(​​InetAddress​​ address,int port,​​InetAddress......
  • 11月16日内容总结——OSI传输层之TCP与UDP协议、应用层简介、socket模块介绍及代码优
    目录一、传输层之TCP与UDP协议1.TCP协议(重要)三次握手建链接四次挥手断连接2.UDP协议3.tcp和udp的对比二、应用层简介三、socket模块1、简介2、基于文件类型的套接字家族3......
  • socket模块
    目录一、socket模块(套接字)1.socket简介2.代码实现3.代码优化一、socket模块(套接字)​socket上应用层与TCP/IP协议通信中间的软件抽象层,帮助我们编写基于网络进......
  • OSI七层协议之传输层,应用层,socket模块简介,socket模块基本使用,黏包问题
    目录OSI七层协议之传输层,应用层,socket模块简介,socket模块基本使用,黏包问题今日内容概要今日内容详细传输层之TCP与UDP协议应用层socket模块socket代码简介代码优化半连接池......
  • 网络编程2 TCP、UDP协议 与socket模块
    TCP与UDP协议1.TCP协议(重点)"""凡事必须有回复才能继续"""三次握手连接-1.TCP协议也称为可靠协议,数据不容易丢失数据不容易丢失的原因......
  • TCP\UDP协议 socket模块
    目录传输层主要协议TCP协议三次握手TCP协议反馈机制四次挥手洪水攻击UDP协议socket模块socket代码简介socket.socket()server.bind()server.accept()sock.recv()sock.send......
  • socket 模块
    socket模块我们知道基于网络编写程序时,需要使用OSI七层协议里的七层,每一层都要写。很复杂很繁琐。socket模块相当于集成了这一块,封装了复杂的接口提空了简单快捷的接......