网络编程TCP

1 网络基础相关的知识

架构:

 

1. C / S架构 : client客户端  server服务器  

 

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

 

2. B / S架构 : browser浏览器  server服务器   隶属C/S架构

 

B / S架构 统一了应用的接口.

通信:

1同一台电脑两个py程序通信  : 打开一个文件

2. 两个电脑如何通信 : 连一个网线

 

3. 多个电脑通信 :

 

ex : 电脑1()找电脑2(目标)

  电脑1首先发送一个请求帧,期中包含(ip192.168.1.1,我的mac地址是xxxxxxxx,ip地址为192.168.1.2主机),将此请求发送给交换机.

  交换机要广播这条消息给其他所有主机

  目标主机接收到消息后,对比发现自己就是被找的主机,回复给交换机信息(ip地址是192.168.1.2,我的mac地址是yyyyyyyyy,请回复给ip地址192.168.1.1,mac地址为xxxxxxx的主机)

  交换机单播形式返回给主机

 

1  mac地址 : 一个物理地址,全球唯一,  类似于身份证

 

head中包含的源和目标地址由来:ethernet规定接入internet的设备都必须具备网卡,发送端和接收端的地址便是指网卡的地址,即mac地址。

 

  mac地址:每块网卡出厂时都被烧制上一个世界唯一的mac地址,长度为48位2进制,通常由12位16进制数表示(前六位是厂商编号,后六位是流水线号)

 

 

2  ip地址:    一个四位点分十进制,它标识了计算机在网络中的位置.

 

  • 规定网络地址的协议叫ip协议,它定义的地址称之为ip地址,广泛采用的v4版本即ipv4,它规定网络地址由32位2进制表示
  • 范围0.0.0.0-255.255.255.255
  • 一个ip地址通常写成四段十进制数,例:172.16.10.1

 

 

 3  交换机的通信方式:

广播

  主机之间“一对所有”的通讯模式,网络对其中每一台主机发出的信号都进行无条件复制并转发,所有主机都可以接收到所有信息(不管你是否需要),由于其不用路径选择,所以其网络成本可以很低廉。有线电视网就是典型的广播型网络,我们的电视机实际上是接受到所有频道的信号,但只将一个频道的信号还原成画面。在数据网络中也允许广播的存在,但其被限制在二层交换机的局域网范围内,禁止广播数据穿过路由器,防止广播数据影响大面积的主机。

4  arp协议 :  通过目标ip地址获取目标mac地址的一个协议.

地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。

  主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址。
  收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。
  地址解析协议是建立在网络中各个主机互相信任的基础上的,网络上的主机可以自主发送ARP应答消息,其他主机收到应答报文时不会检测该报文的真实性就会将其记入本机ARP缓存;由此攻击者就可以向某一主机发送伪ARP应答报文,使其发送的信息无法到达预期的主机或到达错误的主机,这就构成了一个ARP欺骗。ARP命令可用于查询本机ARP缓存中IP地址和MAC地址的对应关系、添加或删除静态对应关系等。相关协议有RARP、代理ARP。NDP用于在IPv6中代替地址解析协议。 

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

      ip地址 + 端口 唯一找到某台电脑上的某一个服务程序

我们知道,一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等,这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP 地址与网络服务的关系是一对多的关系。实际上是通过“IP地址+端口号”来区分不同的服务的。

6  路由器 : 连接网段 , 路由

路由器(Router),是连接因特网中各局域网、广域网的设备,它会根据信道的情况自动选择和设定路由,以最佳路径,按前后顺序发送信号。 路由器是互联网络的枢纽,"交通警察"。目前路由器已经广泛应用于各行各业,各种不同档次的产品已成为实现各种骨干网内部连接、骨干网间互联和骨干网与互联网互联互通业务的主力军。路由和交换机之间的主要区别就是交换机发生在OSI参考模型第二层(数据链路层),而路由发生在第三层,即网络层。这一区别决定了路由和交换机在移动信息的过程中需使用不同的控制信息,所以说两者实现各自功能的方式是不同的。

  路由器(Router)又称网关设备(Gateway)是用于连接多个逻辑上分开的网络,所谓逻辑网络是代表一个单独的网络或者一个子网。当数据从一个子网传输到另一个子网时,可通过路由器的路由功能来完成。因此,路由器具有判断网络地址和选择IP路径的功能,它能在多网络互联环境中,建立灵活的连接,可用完全不同的数据分组和介质访问方法连接各种子网,路由器只接受源站或其他路由器的信息,属网络层的一种互联设备。 
 

 

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

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

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

 

所谓”子网掩码”,就是表示子网络特征的一个参数。它在形式上等同于IP地址,也是一个32位二进制数字,它的网络部分全部为1,主机部分全部为0。比如,IP地址172.16.10.1,如果已知网络部分是前24位,主机部分是后8位,那么子网络掩码就是11111111.11111111.11111111.00000000,写成十进制就是255.255.255.0。

 

  知道”子网掩码”,我们就能判断,任意两个IP地址是否处在同一个子网络。方法是将两个IP地址与子网掩码分别进行AND运算(两个数位都为1,运算结果为1,否则为0),然后比较结果是否相同,如果是的话,就表明它们在同一个子网络中,否则就不是。 

 1 比如,已知IP地址172.16.10.1和172.16.10.2的子网掩码都是255.255.255.0,请问它们是否在同一个子网络?两者与子网掩码分别进行AND运算,
 2 
 3 172.16.10.1:10101100.00010000.00001010.000000001
 4 255255.255.255.0:11111111.11111111.11111111.00000000
 5 AND运算得网络地址结果:10101100.00010000.00001010.000000001->172.16.10.0
 6 
 7  
 8 
 9 172.16.10.2:10101100.00010000.00001010.000000010
10 255255.255.255.0:11111111.11111111.11111111.00000000
11 AND运算得网络地址结果:10101100.00010000.00001010.000000001->172.16.10.0
12 结果都是172.16.10.0,因此它们在同一个子网络。
例如

 10  osi 五层模型:

应用       :  http,https,ftp

传输       :  tcp / udp          四层交换机  四层路由器

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

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

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

 

每层运行常见物理设备

 

 每层运行常见的协议

 

 socket概念

 1socket层

 

 

 2理解socket

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

其实站在你的角度上看,socket就是一个模块。我们通过调用模块中已经实现的方法建立两个进程之间的连接和通信。
也有人将socket说成ip+port,因为ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序。
所以我们只要确立了ip和port就能找到一个应用程序,并且使用socket模块来与之通信。

3.套接字(socket)的发展史

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

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

套接字家族的名字:AF_UNIX

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

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

套接字家族的名字:AF_INET

(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)

 

family :

  一种 : AF_UNIX基于文件类型的套接字(早期socket是源自于unix系统而研发的一个功能,主要是为了同一台电脑上,多个程序直接通信)  unix系统的中心思想是 : 一切皆文件

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

      type:

        一种是基于TCP协议   SOCK_STREAM

        一种是基于UDP协议   SOCK_DGRAM

 

      tcp 协议 : 可靠,面向连接的,面向字节流形式的传输方式

      udp协议 : 不可靠,不面向连接的,面向数据的传输方式,但是它快

套接字(socket)初使用

server.py文件import socket
import time
sk=socket.socket()  # 不传参数,默认使用基于网络类型的套接字, 协议 : TCP

sk.bind(("192.168.12.39",10000))  #  端口的范围是0-65535   但是 0-1023 这些你别用
sk.listen()  # 同时能接受的连接
print(123456)
conn,addr = sk.accept() # 等待接受客户端的连接  阻塞等待
print(789)
print('conn:',conn)
time.sleep(15)
conn.close()
sk.close()
client.py文件

import socket
import time
sk = socket.socket()
sk.connect(("192.168.12.39",10000))
time.sleep(15)
sk.close()

通信

 

server.py文件

import socket

sk=socket.socket()  # 我买一个新手机

sk.bind(("192.168.12.39",10000))  #  我买一个手机卡
sk.listen()  # 开机
print(123456)
conn,addr = sk.accept() # 等待朋友给我打电话
ret=conn.recv(100) # 接受数据,接受100个字节
print(ret.decode("utf-8"),addr)

conn.close()
sk.close()

 

client.py文件
import socket

sk = socket.socket()
sk.connect(("192.168.12.39",10000))
sk.send("我是你哥".encode("utf-8"))
sk.close()

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

与单人通信

 

服务器
import socket
sk=socket.socket()
sk.bind(("127.0.0.1",65534))
sk.listen()
conn,addr=sk.accept()
while 1:
    ret=conn.recv(1024).decode("utf-8")
    print(ret)
    if ret=="q":
        break
    content=input(">>>>")
    conn.send(content.encode("utf-8"))
    if content=="q":
        break
conn.close()
sk.close()

客户端
import socket
sk=socket.socket()
sk.connect(("127.0.0.1",65534))
while 1:
    content=input(">>>>")
    sk.send(content.encode("utf-8"))
    if content == "q":
        break
    ret=sk.recv(1024).decode("utf-8")
    print(ret)
    if ret == "q":
        break
sk.close()

 

与单人轮流通信

 

服务器
import socket
sk=socket.socket()
sk.bind(("127.0.0.1",65534))
sk.listen()
while 1:
    conn,addr=sk.accept()
    while 1:
        ret=conn.recv(1024).decode("utf-8")
        print(ret)
        if ret=="q":
            break
        content=input(">>>>")
        conn.send(content.encode("utf-8"))
        if content=="q":
            break
    conn.close()
sk.close()

客户端
import socket
sk=socket.socket()
sk.connect(("127.0.0.1",65534))
while 1:
    content=input(">>>>")
    sk.send(content.encode("utf-8"))
    if content == "q":
        break
    ret=sk.recv(1024).decode("utf-8")
    print(ret)
    if ret == "q":
        break
sk.close()

 

tcp三次握手一定client先发起请求

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

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

             c  客户端回复 : 可以连接

       四次挥手:  先发起断开连接的请求都可以

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

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

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

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

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

与多人署名轮流聊天

 

服务器
import socket
sk=socket.socket()
sk.bind(("127.0.0.1",6554))
sk.listen()
while 1:
    conn,addr=sk.accept()
    while 1:
        ret=conn.recv(1024).decode("utf-8")
        print(ret)
        if ret== "q":
            break
        content=input(">>>>")
        conn.send(content.encode("utf-8"))
        if content == "q":
            break
    conn.close()
sk.close()
客户端
import socket
sk=socket.socket()
sk.connect(("127.0.0.1",6554))
name=input("输入名字:")
while 1:
    content=input(">>>>")
    use_name=name+":"+content
    sk.send(use_name.encode("utf-8"))
    if content == "q":
        break
    ret=sk.recv(1024).decode("utf-8")
    print(ret)
    if ret == "q":
        break
sk.close()

 

posted @ 2018-08-10 16:03  chenyibai  阅读(248)  评论(0编辑  收藏  举报