Python Socket网络编程(二)局域网内和局域网与广域网的持续通信

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/youand_me/article/details/83109238

前言

       本系列博客是笔者学习Python Socket的过程笔记第二篇,目的在于记录。其中的解释都为自己的见解,仅供参考,如有错误,还望指出。本篇博客是对Python Socket的局域网内两台设备之间的通信,和局域网和广域网(通常是指我们购买的服务器)之间的通信区别,在上一篇博客中,记录了socket模块和初步实现了一台设备(电脑)中的不同进程之间的通信,有兴趣的请前往上一篇博客Python Socket网络编程(一)初识Socket和Socket初步使用。
       这一节的内容不算多,但是我还是单独列出来,原因在于这一块非常重要,其中还有一块关于IP的知识必须掌握才能对网络编程有帮助。

IP地址

  • 简介

       网络之间互连的协议(IP)是Internet Protocol的外语缩写。IP协议中一个非常重要的内容,那就是给因特网上的每台计算机和其它设备都规定了一种地址,叫做“IP 地址”。由于有这种地址,才能对网络上这么多设备进行区分,并且根据某一个IP就能找到一个唯一的设备。但是IP地址也是有区分的,广义上分为私有IP地址(保留IP地址)和公有IP地址(固定IP地址)。

  • 公有IP

       公有IP地址是由INIC(Internet Network Information Center 因特网信息中心)负责。这些IP地址分配给向INIC提出申请并成功注册的组织机构。通过公有IP地址能直接访问因特网,当然公有IP是要钱的。

  • 私有IP

       随着网络的发展,为节省可分配的注册IP地址,有一组IP地址被拿出来专门用于私有IP网络,称为私有IP地址。私有IP地址范围:
       A类: 10.0.0.0~10.255.255.255
       B类:172.16.0.0~172.31.255.255
       C类:192.168.0.0~192.168.255.255
       这些地址是不会被Internet分配的,它们在Internet上也不会被路由,虽然它们不能直接和Internet网连接,但通过技术手段仍旧可以和 Internet通讯(NAT技术)。公网IP是直接与英特网连接可以直接访问网络(上网),而私有IP地址则是在局域网中使用的IP地址,私有IP是不能直接上网的(无法直接和公网通信),当私有网络内的主机要与位于公网上的主机进行通讯时必须经过地址转换,将其私有地址转换为合法公网地址才能对外访问。也就是要使用NAT-Network Address Translation 网络地址转换技术。
       那么平时我们的电脑是如何上网的呢?比如我们办理了电信宽带,拉一根网线连接到我们的电脑,我们的电脑就能上网了。实质上此时我们的电脑是一个私有IP,电信那边购买了一个公有IP,我们电脑和电信的公有IP之间有一个NAT技术设备,也就是说我们能上网是通过电信的公有IP实现的。
       如果在家安装了路由器我们的多台电脑连接在这个路由器上,那么这些电脑直接就构成了局域网,在这几台电脑上可以直接进行局域网的通信。但是你家里构成的局域网和公司的局域网是不能通过局域网通信的。

       在这里记录私有IP和公有IP的原因在于socket网络通信需要区别,以便我们知道哪些IP之间是不能通信的,哪些IP之间是可以通信的。从上述原理我们就知道同一个局域网内的设备A和设备A,设备A和设备B,广域网内的设备A和设备B可以实现双向连接通信,局域网的设备A和广域网的设备B可以单向连接(只能由局域网去连接广域网,也就是局域网是客户端,广域网是服务端;因为广域网的IP是固定且唯一的,局域网连接网络通过指定这个公有IP就能找到这台计算机,找的过程是局域网连接电信网络,通过NAT技术将这个局域网私有IP转换为公有IP然后再去和指定的公有IP通信,这样就可以找到指定的公有IP,相反私有IP是不能被公有IP找到的)通信。不同局域网之间的设备不能通信。

局域网之间网络通信

  • 前提

       在上一篇博客中实现的是本机的不同进程的通信,这里要实现同一局域网内两台电脑的通信,我这测试的两台电脑IP分别为A(Ubuntu16.04):192.168.27.165和B(Windows10):192.168.27.238,我们如何知道两台电脑是否是同一局域网呢。Windows电脑按win+r输入cmd打开cmd命令控制台,输入命令ping 192.168.27.165(我的B电脑是Windows的,我用它去ping我的A电脑IP,能ping通则说明使用socket电脑B能连接上A,也就是A可以运行服务器程序,B运行客户端程序去连接A,如果在B上也能ping通A则说明AB都能做服务端和客户端);Ubuntu系统ctr+alt+t打开命令行,输入命令ping 192.168.27.238,两边都能ping通则说明在一个局域网上。

       我这里随便选了B作为服务器端,要想A连接上B电脑建立通信,那么我们需要先将B的防火墙关掉。

  • 功能描述

       由于要实现同一局域网的两台设备的持续通信,找一个设备做服务端,建立socket,监听B机IP的6688端口等待客户端来连接,一旦有一个客户端来连接了就打印连接信息,然后循环等待连接的客户端发送数据,接收到客户端传来的数据后,就反馈给客户端收到信息了,直至接收到quit信息才退出循环结束连接;客户端程序先建立socket套接字,然后去连接B机的IP和6688端口进程,连接成功后循环等待控制台输入数据,接受到输入的数据后发送到服务端,然后结束连接。

  • 源码

       在B(服务端)新建一个server.py文件,然后运行程序,内容如下:

import socket


# 创建一个socket套接字,该套接字还没有建立连接
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定监听端口,这里必须填本机的IP192.168.27.238,localhost和127.0.0.1是本机之间的进程通信使用的
server.bind(('192.168.27.238', 6688))
# 开始监听,并设置最大连接数
server.listen(5)

print(u'waiting for connect...')
# 等待连接,一旦有客户端连接后,返回一个建立了连接后的套接字和连接的客户端的IP和端口元组
connect, (host, port) = server.accept()
print(u'the client %s:%s has connected.' % (host, port))

while True:
    # 接受客户端的数据
    data = connect.recv(1024)
    # 如果接受到客户端要quit就结束循环
    if data == b'quit' or data == b'':
        print(b'the client has quit.')
        break
    else:
        # 发送数据给客户端
        connect.sendall(b'your words has received.')
        print(b'the client say:' + data)

# 结束socket
server.close()

       同时在A(客户端)新建一个client.py文件,然后运行程序,内容如下:

import socket


# 创建一个socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 主动去连接局域网内IP为192.168.27.238,端口为6688的进程
client.connect(('192.168.27.238', 6688))

while True:
    # 接受控制台的输入
    data = input()
    # 对数据进行编码格式转换,不然报错
    data = data.encode('utf-8')
    # 如果输入quit则退出连接
    if data == b'quit':
        print(b'connect quit.')
        break
    else:
        # 发送数据
        client.sendall(data)
        # 接收服务端的反馈数据
        rec_data = client.recv(1024)
        print(b'form server receive:' + rec_data)

# 发送数据告诉服务器退出连接
client.sendall(b'quit')
client.close()
  • 运行结果

在这里插入图片描述
在这里插入图片描述

       上面第一个截图是客户端(hello、nice to meet you.、I wanna quit.、quit都是输入的数据),第二个是服务端截图。

局域网与广域网网络通信

  • 前提

       实现局域网到广域网的通信,首先需要一台连网的本地计算机和一个服务器(比如购买的阿里云服务器,必须是连接英特网的)。只要本地的计算机能ping通服务器的IP就行了(服务器是无法ping通本地的计算机的,原因前面已经介绍)。

  • 源码

       由于局域网和广域网只能建立单向连接的socket通信,也就是说只能将服务器作为服务端来等待客户端的连接。所以我们将服务器作为服务端,在服务器上新建一个server.py文件(和局域网之间通信的服务端server.py没什么区别,只是绑定的IP为服务器自己的IPserver.bind(('192.168.27.238', 6688))改为server.bind(('220.181.111.188', 6688))220.181.111.188是百度的IP,改为你的服务器IP),然后在本机建一个client.py文件,内容和局域网之间通信的client.py一致,只是连接的IP改为服务器的IP(client.connect(('192.168.27.238', 6688))改为client.connect(('220.181.111.188', 6688)),这里就不冗余的贴代码了)。

结语

       到此局域网内和局域网与广域网的持续通信初步实现已经差不多了,不过上述代码也只能是一对一的通信,一对多不是本篇博客的内容,因为客户端一般都不会只有一个,所以这个一对一不能满足我们的常用需求。在下一篇博客会介绍多线程实现多客户端连接服务器,与服务器通信。

上一篇:Python Socket网络编程(一)初识Socket和Socket初步使用
下一篇:Python Socket网络编程(三)Socket多线程实现多客户端与服务器通信

猜你喜欢

转载自blog.csdn.net/youand_me/article/details/83109238