10.16 知识总结(Socket抽象层、基于TCP协议的程序、基于UDP协议的编程、粘包现象)

一、Socket抽象层(socket编程)

       1.1 socket是什么?

    Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。 

          1.2  套接字发展史及分类

     套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。

基于文件类型的套接字家族:
     套接字家族的名字:AF_UNIX

基于网络类型的套接字家族
     套接字家族的名字:AF_INET

      1.3套接字工作流程

         服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

如图所示:

二、  基于TCP协议的套接字(socket)编程

       2.1 客户端和服务端应该是谁先发送消息

         客户端先发送消息,需要服务端先运行起来

       2.2 服务端代码

import socket
from socket import AF_INET
# socket.socket() # AF_INET, type=SOCK_STREAM: 基于TCP协议的
server=socket.socket(family=AF_INET, type=socket.SOCK_STREAM) # AF_INET, type=SOCK_DGRAM: 基于UDP协议的

     2.3  绑定IP地址和port

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

   2.4  服务端做监听,也称为是半链接池(服务端能够同时等待客户端的数量)

server.listen(3)
print(123)

2.5 客户端代码

import socket
from socket import AF_INET
client=socket.socket(family=AF_INET, type=socket.SOCK_STREAM)
# socket.socket()

client.connect(('127.0.0.1', 8000))

2.6 加上通信和通信循环

import socket
from socket import AF_INET
# socket.socket() # AF_INET, type=SOCK_STREAM: 基于TCP协议的
server=socket.socket(family=AF_INET, type=socket.SOCK_STREAM) # AF_INET, type=SOCK_DGRAM: 基于UDP协议的

# 绑定IP地址和port
server.bind(('127.0.0.1', 8000))

# 服务端做监听,也称为是半链接池(服务端能够同时等待客户端的数量)
server.listen(3)

while True:
    # 该接收客户端发来的消息
    sock, addr = server.accept() #  """我们知道代码运行到这里,就会卡主,等待客户端开发链接和发送消息"""
    """sock:当前链接的客户端的链接, addr:就是客户端的地址:ip,port"""

    while True:
        # 想拿到客户端实际发过来的数据
        try:
            """客户端发送过来的数据是个空,或者"""
            data=sock.recv(1024) # 接收的数据类型是bytes类型,二进制的 1024 代表接收的最多的字节数
            print("接收客户端的数据:",data)
            # 要给客户端返回一个数据
            sock.send(data.upper()) # 发送的数据是字节类型的
        except Exception as e:
            print(e)
            break
    # 关闭链接
    sock.close()

server.close()

###########################客户端####################################
import socket
from socket import AF_INET
client=socket.socket(family=AF_INET, type=socket.SOCK_STREAM)
# socket.socket()

client.connect(('127.0.0.1', 8000))

while True:
    send_data = input('请输入你要发送给服务端的数据:')

    # 开始给服务端发送消息
    client.send(send_data.encode('utf-8'))

    # 接收服务端发来的消息
    data=client.recv(1024)
    print("服务端发来的消息:", data)
client.close()

三、 基于UDP协议的套接字编程

     3.1 客户端

import socket

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # 数据报协议-》UDP

while True:
    msg = input('>>: ').strip()  # msg=''
    client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080))
    data, server_addr = client.recvfrom(1024)
    print(data)

client.close()

  3.2  服务端

import socket

server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # 数据报协议-》UDP
server.bind(('127.0.0.1', 8080))

while True:
    """client_addr: 客户端的地址"""
    data, client_addr = server.recvfrom(1024) # 接收的最大字节数
    print('===>', data, client_addr)
    server.sendto(data.upper(), client_addr)

server.close()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值