day-31网络编程


socket


什么是socket 翻译为套接字


是一套编程接口,内部封装了一堆底层协议,隐藏了内部复杂的实现细节,提供简单的使用接口


咱们只要按照socket编程接口来编写出的代码,就已经遵循了各种协议


简单的说就是一个封装好的模块


要学习的就是模块的使用方法


 


socket的发展


最开始socket使用来完成进程间通讯的,并不是用来网络通讯,那时候还没有网络


后来有了网络之后 .基于之前的socket来进行了更新 使其可以支持网络通讯


所以socket分为两种类型


AF_UNIX : 进程间通讯


AF_INET : 网络通讯  


server:

import socket
搭建服务器:
# 参数1指定 socket类型AF_INET 表示网络类型
#参数2指定的传输协议为 SOCK_STREAM表示TCP协议 SOCK_DGRAM UDP协议
# 默认就是 网络类型  TCP协议

server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 作为服务器必明确自己的ip和端口号   并且不应该变化
注意:需要参数是一个元组 ip一定本机ip 端口就是普通整数

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

开始监听端口
server.listen()

while True:
第一个是表示客户端的socket    第二个客户端的地址信息
# accept  是一个阻塞函数  会一直等到有客户端链接过来 在继续执行,之间完成三次握手
    client,addr=server.accept()
while True:
try:
        接收数据 注意都是用表示客户端的socket来收发数据
        1024是缓冲区  就是一个临时的容器 
        缓冲区大小 不能随便写 太大会导致内存溢出 太小效率低 在内存能够承受的情况下 大一些
            date=client.recv(1024)
        
      # 1.在linux中 对方如果强行下线了  服务器不会抛出异常 只会收到空消息
      # 所以得加上判断 如果为空则意味着 对方下线了 应该关闭链接 跳出循环
      #2. windows上正常关闭 也会收到空消息

if not date:
client.close()
break
print(date.decode('utf-8'))
        发送数据 注意都是用表示客户端的socket来收发数据
        # 解码时必须保证双方统一编码方式



         发送数据时  对方可能也会异常下线 也会抛出异常
       接收数据 和发送数据都应该放到try
            client.send(date.upper()+'你好'.encode('utf-8'))
except ConnectionResetError as e:
print(e)
       如果对方下线了  那服务器也应该关闭对应的客户端对象
       
       完成四次挥手
            client.close()
break

关闭服务器
server.close()


clint:
import socket
搭建客户端
client=socket.socket()
connect本质实在进行三次握手   也是一个数据传输的过程  如果服务器没有立马响应 也会阻塞
连接服务器ip和端口号
作为客户端 ip和端口可以变化   所有系统会自动分配随机端给客户端

client.connect(('127.0.0.1',8080))
while True:
msg=input('>>>')
if not msg:
continue
if msg == 'q':
break
  
   发送数据   注意发送的内容只能是二进制  bytes
  # 发送数据   本质上是把数据交给操作系统来进行发送   一旦数据交给了操作系统 后续的发送
  # 应用程序就无法控制了 ,send一般不会卡 当然 如果数据量很大就会阻塞
    client.send(msg.encode('utf-8'))
try:
  
  接收数据   注意接收的内容是二进制  bytes
  # 接收数据是从操作系统缓存区读取数据   如果当前还没有任何数据 就会进入阻塞
  # 会一直等到有数据到来 再继续执行
   另外服务器有可能出现异常,所以接收数据需要try一下
        date=client.recv(1024)
print(date.decode('utf-8'))
except:
print('服务器炸了')
# 客户端执行close 是正常关闭链接   会给服务器送空字节  用于表示要断开链接
client.close()

常见异常:
1.如果已经开启了服务器  再次运行将会抛出 端口占用异常  把之前开启的服务器关掉即可
2.有些情况   明明已经关闭了进程 但是 还是端口占用  
 可能是进程正在后台运行 可以通过端口查出进程 进行关闭
windows下
netstat -ano | findstr 9898
tasklist | findstr 进程id 拿到进程名称
taskkill /f /t /im 进程名称
3.修改服务器端口(后期无法修改)

三次握手,四次挥手

数据收发过程


原文地址:https://www.cnblogs.com/klw1/p/10939824.html