网络编程基础:

网络基础相关知识:

  1, 架构

    (1) C/S 架构 : client 客户端 和 server 服务器端

       优势 : 能充分发挥PC机的性能

          B/S 架构 : browser 浏览器 和 server 服务器端

      其隶属于C/S架构,  B/S架构统一了应用的接口 

   

     (2) 通信的事 : 

      1) 同一台电脑上的通信: 打开一个文件

      2) 两台电脑通信: 一根网线

      3) 多个电脑通信:

        电脑1(源) 与电脑2(目标)

        电脑1 发送一个请求帧, 其中包含了[电脑1 的 IP地址(192.168.1.11), 和电脑1 的MAC物理地址(XXXX)以及目标电脑2 的IP地址(192.1868.1.12)], 将请求发给交换机,交换机广播这条消息,给其他计算机,然后目标机接收到消息后,对比IP,确认自己是背照的机器,回复交换机信息(其中包含目标电脑的IP, MAC ,并将这些信息发送给 电脑1)交换机单播形式返回给电脑1

      

注意:

1, Mac地址: 是一个物理地址(每台电脑唯一),全球唯一

2, IP地址: 是一个由四位点分十进制组成. 他标志了计算机在网络中的位置.

3, 交换机的信号方式:

  广播(吼一嗓子), 单播(一对一), 组播(一对多)

4, arp协议: 通过目标IP地址,获取目标的MAC(物理)地址的一个协议.

5, 端口: 操作电脑为本电脑上每一个运行的软件随机分配的一个端口,其他电脑上的程序可以通过端口获取这个程序.

6, 路由器: 链接不同网段, 路由是一个过程

7, 网关 : 类似于一个局域网的入口和出口.

8, 网段 : 一个局域网内的ip地址范围

9, 子网掩码: 子网掩码 & ip地址    得到网段

10, osi-----开放系统互联(Open System Interconnection)

  osi五层模型

    应用层      http, https, ftp

    传输层      

    网络层      ip协议        路由器  三层交换机

    数据链路层    arp协议         以太网交换机  网卡  网桥

    物理层      传输电信号      集线器  网线  光纤

重点顺序:

arp协议

路由器与交换机的区别?

tcp协议和udp协议的特点,tcp协议的编码

软件开发架构

osi五层模型

socket模块

  socket 又叫做套接字

  其有很多种类型,主要学习两种: TCP协议, UDP协议

  TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字(socket), 或插口

  套接字用(IP地址 + 端口号)  表示

  sk = socket.socket(family = AF_INET, type = SOCK_STREAM)

  family有两种类型:

  第一种:

   AF_UNIX基于文件类型的套接字(早起socket[套接字]是源自于Unix系统而研发的一个功能, 主要是为了同一台电脑上, 多个程序之间通信.)

   Unix系统的中心思想: 一切皆文件

  第二种:   AF_INET  基于网络类型的套接字

  type:

  一种是基于TCP协议    SOCK_STREAM  

  SOCK_STREAM套接口(流套接口)的性质(TCP协议的接口)

    1,不保留任何消息边界 

      举一个例子:本地主机通过两次独立的write(2)调用向远程主机发送数据,

      第一次本地进程写入25字节的数据,并通过套接口发送到远程进程,第二次再写入

      30字节的数据发往远程进程,总共55字节的数据,而远程进程从套接口接收数据时,

      将消息作为一个完整的单元来接收,或是通过若干次独立的读操作来将数据取走,

      即接受端并不知道这55字节的数据是分25字节和30字节两次来发送的。

     2, 有序性

        可以保证接收的数据字节与发送的顺序完全一致(意味着通信之前必须建立一个链接)

     3, 无错性

        可以保证接收的数据在接受端被无错的接收, 如果有错误发生, 在尝试完所有的错

        误恢复措施后仍无法消除错误, 所进行的错误恢复措施尝试是完全自动的, 不需要编程者的指导.

一种是基于UDP协议    SOCK_DGRAM

UDP协议: 不可靠的, 不面向连接的, 面向数据报的传输方式,速度快.(一般应用于网络电话等)

允许一个服务器同时和多个客户端通信.

  SOCK_DGRAM套接口((UDP协议的接口))

    特征:

      1, 分组再发送后, 可能无序的到达接收端

      2, 分组可能丢失, 如果发生丢失, 不会才去任何补救的措施, 而且接收端也不必直到分组丢失.

      3, 数据报分组有尺寸大小的限制, 如果超出限制, 在某些路由器节点上就无法传送.

      4, 分组是在不建立链接的情况下被发送到远程进程的.

  TCP协议: 可靠地, 面向连接, 面向字节流的传输方式(可用于聊天室等.)

    回环地址: 127.0.0.1 , 每个计算机都有的这么一个本机地址, 只能被本机识别, 不会被其他机器识别.

  TCP的三次握手:  一定是client先发起的请求

      a 客户端发起请求连接服务器

      b 服务器返回: 接收到请求, 并要求链接客户端

      c 客户端回复: 可以连接

  四次挥手: 谁先发起断开连接都可以

      a 客户端发起断开连接的请求:

        意思是: 我想和你断开连接,我没有数据要继续发送了,但是如果你有数据要继续发送给我, 我可以继续接收.

      b 服务器回复: 我接收到你的请求了,

      c 服务器发送: 我已经准备好断开连接了

      d 客户端回复: 收到你的信息, 断开连接

ACK : 确认收到

SYN : 请求链接的这么一个标识

FIN : 请求断开这么一个标识

3 pycharm带颜色输出:

33[字体颜色;背景颜色m 数据 33[0m

print('33[32;43m abc ')
print('abcsdasd 33[0m')
print('asdfgggg')

TCP协议编程:

客户端(client):

 1 import socket
 2 
 3 sk = socket.socket()  # 不传参数, 默认使用基于子类网络类型的套接字. 使用协议: TCP
 4 sk.connect(('127.0.0.1', 65534))  # 链接
 5 
 6 while 1:
 7     msg = input('>>>')
 8     sk.send(msg.encode('utf-8'))
 9     if msg == 'q':
10         break
11     msg_r = sk.recv(1024).decode('utf-8')
12     if msg_r == 'q':
13         break
14     print(msg_r)
15 
16 sk.close()  # 结束链接
View Code

服务器端(server):

 1 import socket
 2 
 3 sk = socket.socket()
 4 sk.bind(('127.0.0.1', 65534))
 5 sk.listen()
 6 while 1:
 7     conn, addr = sk.accept()
 8     while 1:
 9         msg_r = conn.recv(1024).decode('utf-8')
10         if msg_r == 'q':
11             break
12         print(msg_r)
13         msg_s = input('>>>')
14         conn.send(msg_s.encode('utf-8'))
15         if msg_s == 'q':
16             break
17     conn.close()
18 sk.close()
代码

UDP协议编程:

客户端(client):

import socket
sk = socket.socket(type=socket.SOCK_DGRAM) # UDP协议  实例化对象
name = input('请输入你的名字:')
while 1:
    msg_s = input('>>>')
    info = name + ' : ' + msg_s
    sk.sendto(info.encode('utf-8'), ('127.0.0.1', 8090)) # 发送给谁的消息
    msg_r, addr = sk.recvfrom(1024)# 接收来自于哪里的消息
    print(msg_r.decode('utf-8'))
    if msg_r.decode('utf-8') == 'q':  # 当输入'q'的时候退出交互
        break
sk.close()
服务器端(server):
import socket
sk = socket.socket(type=socket.SOCK_DGRAM) # UDP协议  实例化对象
sk.bind(('127.0.0.1',8090))  # 绑定IP地址和端口号
dic = {'hanfei': '33[43m',}
while 1:
    msg_r, addr = sk.recvfrom(1024)  # 接收消息
    msg_r = msg_r.decode('utf-8')  # 进行转码
    if msg_r.split(':')[1].strip() == 'q': # 如果输入'q' 退出
        break
    name = msg_r.split(':')[0].strip()
    color = dic.get(name, '')
    print('%s %s 33[0m' %(color, msg_r))

    msg_s = input('>>>')
    sk.sendto(msg_s.encode('utf-8'),addr)  # 发送消息 到服务器
sk.close()

自定义一个socket模块

 1 import socket
 2 
 3 
 4 class MySocket(socket.socket):# 继承自 socket文件中的socket类,此时socket就是父类
 5     def __init__(self,encoding='utf-8'):
 6         self.encoding = encoding
 7         super(MySocket, self).__init__(type=socket.SOCK_DGRAM)#  执行父类socket中的__init__方法
 8 
 9     def my_sendto(self,msg,addr):
10         return self.sendto(msg.encode(self.encoding),addr)# 调用父类中的sendto方法
11 
12     def my_recvfrom(self,num):
13         msg_r,addr = self.recvfrom(num)# 调用父类的recvfrom方法
14         return msg_r.decode(self.encoding),addr
自定义socket模块代码
1 from My_UDP import MySocket
2 sk = MySocket()
3 sk.my_sendto('abcabc中国',('127.0.0.1',8080))
4 sk.close()
引用自定义模块的服务器端(client)代码
1 from My_UDP import MySocket
2 sk = MySocket()
3 sk.bind(('127.0.0.1',8080))
4 msg,addr = sk.my_recvfrom(1024)
5 print(msg)
6 sk.close()
引用自定义模块的服务器端(server)代码
原文地址:https://www.cnblogs.com/hfbk/p/9476126.html