编程基础之socket编程

  1. 学socket编程的意义
  2. OSI七层
  3. socket层
  4. socket是什么
  5. 套接字分类
  6. 套接字工作流程
  7. 基于TCP的套接字
  8. 基于UDP的套接字
  9. 粘包现象
  10. 什么是粘包
  11. 解决粘包的方法
  12. 认证客户端的链接合法性
  13. socketserver实现并发

1.学socket编程的意义

  客户端/服务器架构(c/s架构)

  1. 硬件c/s架构(打印机)
  2. 软件c/s架构

      互联网中处处是C/S架构

    如某网站是服务端,你的浏览器是客户端(B/S架构也是C/S架构的一种)

    腾讯作为服务端为你提供视频,你得下个腾讯视频客户端才能看它的视频

  C/S架构与socket的关系:

    socket就是为了更加便捷的完成C/S架构的开发


2.OSI七层

  一个完整的计算机系统是由硬件、操作系统、应用软件三者组成,具备了这三个条件,一台计算机系统就可以自己跟自己玩了(打个单机游戏,玩个扫雷啥的)

  如果你要跟别人一起玩,那你就需要上网了,什么是互联网?

  互联网的核心就是由一堆协议组成,协议就是标准,比如全世界人通信的标准是英语。

  人们按照分工不同把互联网协议从逻辑上划分了层级:

    互联网协议按照功能不同分为osi七层或tcp/ip五层或tcp/ip四层:

    

    每层常用的物理设备:

    

  为何学习socket一定要先学习互联网协议:    

  1.首先:本节课程的目标就是教会你如何基于socket编程,来开发一款自己的C/S架构软件

  2.其次:C/S架构的软件(软件属于应用层)是基于网络进行通信的

  3.然后:网络的核心即一堆协议,协议即标准,你想开发一款基于网络通信的软件,就必须遵循这些标准。

  4.最后:就让我们从这些标准开始研究,开启我们的socket编程之旅

     


3.socket层

  socket层到底在哪里?

  


4.socket是什么

   Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口

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

  所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。

    也有人将socket说成ip+port,ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序,ip地址是配置到网卡上的,而port是应用程序开启的,ip与port的绑定就标识了互联网中独一无二的一个应用程序;

    而程序的pid是同一台机器上不同进程或者线程的标识


5.套接字分类

  套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。

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

  unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信

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

  还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现。

  AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET。


6.套接字工作流程

  

  服务器端:

    服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。

  客户端:

    初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。

  客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。


  socket()模块函数使用方法

 1 import socket
 2 socket.socket(socket_family,socket_type,protocal=0)
 3 #socket_family 可以是 AF_UNIX 或 AF_INET。socket_type 可以是 SOCK_STREAM 或 SOCK_DGRAM。protocol 一般不填,默认值为 0。
 4 
 5 #获取tcp/ip套接字
 6 tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 7 
 8 #获取udp/ip套接字
 9 udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
10 
11 #由于 socket 模块中有太多的属性。我们在这里破例使用了'from module import *'语句。使用 'from socket import *',我们就把 socket 模块里的所有属性都带到我们的命名空间里了,这样能 大幅减短我们的代码。
12 #例如tcpSock = socket(AF_INET, SOCK_STREAM)

   服务端套接字函数:

  s.bind()           绑定(主机,端口号)到套接字

  s.listen()          开始TCP监听

  s.accept()        被动接受TCP客户的连接,(阻塞式)等待连接的到来

  客户端套接字函数:

  s.connect()        主动初始化TCP服务器连接

  s.connect_ex() connect()  函数的扩展版本,出错时返回出错码,而不是抛出异常

  公共用途的套接字函数:

  s.recv()          接收TCP数据
  s.send()         发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
  s.sendall()        发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)
  s.recvfrom()        接收UDP数据
  s.sendto()         发送UDP数据
  s.getpeername()      连接到当前套接字的远端的地址
  s.getsockname()      当前套接字的地址
  s.getsockopt()       返回指定套接字的参数
  s.setsockopt()       设置指定套接字的参数
  s.close()         关闭套接字

  面向文件的套接字的函数:

  s.fileno()         套接字的文件描述符

  s.makefile()       创建一个与该套接字相关的文件

  面向锁的套接字方法:

  s.setblocking()      设置套接字的阻塞与非阻塞模式

  s.settimeout()       设置阻塞套接字操作的超时时间

  s.gettimeout()       得到阻塞套接字操作的超时时间


7.基于TCP的套接字

猜你喜欢

转载自www.cnblogs.com/jjb1997/p/11200104.html