网络编程基础(TCP通信)

网络编程基础

一、 IP地址

 IP地址的概念:IP地址就是表示网络中的设备的一个地址

1.1 IP地址的表现形式

在这里插入图片描述

  • IP地址分为两类:IPv4(十进制组成)和IPv6

1.2 IP地址的作用

IP地址的作用是表示网络中共唯一的一台设备的,也就是说通过IP地址能过找到网络中某台设备
  • IP地址的效果图
    在这里插入图片描述

1.3 查看IP地址

  • Linux和mac OS使用 ifconfig 这个命令
  • Windows 使用 ipconfig 这个命令

1.4 检查网络是否正常

  • 检查网络是否正常使用 ping 命令:ping ip地址
  • 检查是否能上公网:ping www.baidu.com
  • 检查是否再同一个局域网内 ping 当前局域网的ip地址
  • 检查本地网卡是否正常:ping 127.0.0.0.1

二、端口和端口号的介绍

2.1 端口

端口是传输数据的通道,好比教室的门,是数据传输必经之路。
  • 效果图
    在这里插入图片描述

2.2 什么是端口号

操作系统为了统一管理这么多端口,就对端口进行了编号,这就是端口号,端口号其实就是一个数字,一共有65536个。

通信流程:通过ip地址找到对应的设备,通过端口号找到对应的端口,然后通过端口把数据传输给应用程序

2.21端口号的分类
  • 知名端口号:范围0-1023
    这些端口固定分配给一些服务,比如21端口发呢配给FTP(文件传输协议)服务,25端口分配给SMTP(简单邮件传输协议)服务,80分配给HTTP服务
  • 动态端口号:范围(1024-65535)

三、TCP介绍

3.1 网络应用程序之间的通信流程

数据在发送之前需要选中一个对应的传输协议,保证程序之间按照指定的传输规则进行数据的通信。

3.2 TCP的概念

TCP简称传输控制协议,它是一种面向连接的、可靠的、基于字节流的传输层通信协议。 
  • TCP通信步骤
    1、创建连接
    2、传输数据
    3、关闭连接

3.3 TCP的特点

1、面向连接

  • 通信双方必须先建立连接才能进行数据的传输,数据阐述完成后,双方必须断开此连接,以释放系统资源

2、可靠传输

  • TCP采用发送应答机智
  • 超时重传
  • 错误校验
  • 流量控制和阻塞管理

四、socket的介绍

4.1 socket的概念

socket(套接字)是进程之间通信的一个工具,进程之间进行网络通信需要基于socket。

socket效果图:
在这里插入图片描述

4.2 socket的作用

负责进程直接按的网络数据传输,数据的搬运工	

五、TCP网络应用程序开发流程

TCP网络应用程序开放分为:

  • TCP客户端程序开发
  • TCP服务端程序开发

5.1 TCP客户端程序开发流程的介绍

步骤说明:
1、创建客户端套接字对象
2、和服务端套接字建立连接
3、发送数据
4、接收数据
5、关闭客户端套接字

5.2 TCP服务端程序开发流程的介绍

步骤说明:
1、创建服务端套接字对象
2、绑定端口号
3、设置监听
4、等待接收客户端的连接请求
5、接收数据
6、发送数据
7、关闭套接字

六、TCP通信

6.1 TCP客户端程序开发

6.11 socket 类的介绍
  • 导入socket模块:import socket
  • 创建客户端socket对象:socket.socket(AddressFamily,Type)
    参数说明:
    AddressFamily:表示IP地址类型,分为IPv4和IPv6
    Type:表示传输协议类型

方法说明:

  • connect(host,port):表示和服务端套接字建立连接
  • send(data)表示发送数据,data是二进制数据
  • recv(buffersize):表示接收数据,buffersize是每次接收数据的长度
    工具:网络调试助手模拟服务端
    客户端代码:
import socket


if __name__ == '__main__':

#1.创建tcp客户端套接字
#AF_INET:IPv4地址类型
#SOCK_STREAM:TCP传输协议类型
    tcp_client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    #2.和服务端建立连接
    tcp_client_socket.connect(("172.18.1.27",9090))

    send_content = "你好,我是客户端小白!!!"
    #对字符串进程编码成为二进制数据
    # send_data= send_content.encode("utf-8")
    send_data= send_content.encode("gbk")
    #3.发送数据到服务端
    #windows里面的网络调试助手使用的gbk编码
    #linux 里面的网络台哦是助手使用的utf-8编码
    tcp_client_socket.send(send_data)
    #4.接收服务端的数据
    recv_data = tcp_client_socket.recv(1024)
    #对二进制数据进行解码
    recv_content = recv_data.decode("gbk")

    print("接收服务端的数据为:",recv_content)

    #5.关闭套接字
    tcp_client_socket.close()

网络调试助手下载地址:http://free.cmsoft.cn/download/cmsoft/assistant/netassist5.0.2.zip

6.2 TCP服务端程序开发示例

6.21 socket 类的介绍
  • 导入socket模块:import socket
  • 创建服务端socket对象:socket.socket(AddressFamily,Type)
    参数说明:
    AddressFamily:表示IP地址类型,分为IPv4和IPv6
    Type:表示传输协议类型

方法说明:

  • bind(host,port):表示绑定端口号,port是端口号,ip地址一般不指定,表示本机任何一个IP地址都可以
  • listen(backlog):表示设置监听,backlog参数表示等待建立连接的个数
  • accept():表示等待接收客户端的连接请求
  • send(data)表示发送数据,data是二进制数据
  • recv(buffersize):表示接收数据,buffersize是每次接收数据的长度

服务端代码

import socket

if __name__ == '__main__':

    #1、创建tcp服务端套接字
    #AF_INET:ipv4,AF_INET6:ipv6
    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    #2、绑定端口号
    #第一个参数表示ip地址,
    #第二个参数表示端口号
    tcp_server_socket.bind(("",9090))
    #3、设置监听
    #128:表示最大等待建立连接的个数
    tcp_server_socket.listen(128)
    #4、等待接收客户端的连接请求
    #注意点:每次当客户端和服务端建立连接成功会返回一个新的套接字
    # result = tcp_server_socket.accept()
    new_client,ip_port = tcp_server_socket.accept()
    # tcp_server_socket只负责等待接收客户端的来凝结请求,收发消息不适用该套接字
    print("客户端的ip和端口号为:",ip_port)
    #5、接收客户端的数据
    #收发消息都使用返回的这个新套接字
    recv_data =  new_client.recv(1024)
    #对二进制数据进行解码变为字符串
    recv_content = recv_data.decode("gbk")
    print("接收客户端的数据为:",recv_content)
    #6、发送数据到客户端
    send_content = "问题正在处理中。。。"
    #对字符串进行编码
    send_data = send_content.encode("gbk")
    new_client.send(send_data)
    #关闭服务与客户端套接字,表示和客户端终止通信
    #7、关闭服务端套接字, 表示服务端以后不再等待接收客户端的连接请求
    tcp_server_socket.close()

6.3 解决端口号复用问题

当客户端和服务端建立连接后,服务端程序退出后端口号不会理解释放,需要等待大概1-2分钟

解决办法:

  • 更换端口号
  • 设置端口号复用,让服务端程序退出后端口号立即释放
    1): 表示当前套接字
    2): 设置端口号复用
    3): 设置端口号复用选项对应的值
tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)

七、案例

7.1 tcp服务端服务于多个客户端

多人版tcp服务端程序代码

import socket
import threading

# 处理客户端请求的认为
def handle_client_request(ip_port,new_client):
    print("客户端的ip和端口号为:", ip_port)
    # 5、接收客户端的数据
    # 收发消息都使用返回的这个新套接字
    #循环接收客客户端的消息
    while True:
        recv_data = new_client.recv(1024)
        if recv_data:
            print("接收到的数据长度为:",len(recv_data))
            # 对二进制数据进行解码变为字符串
            recv_content = recv_data.decode("gbk")
            print("接收客户端的数据为:", recv_content,ip_port)
            # 6、发送数据到客户端
            send_content = "问题正在处理中。。。"
            # 对字符串进行编码
            send_data = send_content.encode("gbk")
            new_client.send(send_data)
        else:
            # 客户端下线了
            print("客户端下线了",ip_port)
            break
    # 关闭服务与客户端套接字,表示和客户端终止通信
    new_client.close()


if __name__ == '__main__':

    #1、创建tcp服务端套接字
    #AF_INET:ipv4,AF_INET6:ipv6
    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #设置端口号复用,让服务端程序退出后端口号立即释放
    # 1): 表示当前套接字
    # 2): 设置端口号复用
    # 3): 设置端口号复用选项对应的值
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

    #2、绑定端口号
    #第一个参数表示ip地址,
    #第二个参数表示端口号
    tcp_server_socket.bind(("",9090))
    #3、设置监听
    #128:表示最大等待建立连接的个数
    tcp_server_socket.listen(128)
    #4、等待接收客户端的连接请求
    #注意点:每次当客户端和服务端建立连接成功会返回一个新的套接字
    # result = tcp_server_socket.accept()
    #循环等待客户端的连接请求
    while True:
        new_client,ip_port = tcp_server_socket.accept()
        # tcp_server_socket只负责等待接收客户端的来凝结请求,收发消息不适用该套接字
        # 当客户端和服务端建立连接成功创建子线程,让子线程专门负责接收客户端的消息
        sub_thread = threading.Thread(target=handle_client_request,args=(ip_port,new_client))
        #设置守护主线程,主线程退出子线程直接销毁
        sub_thread.setDaemon(True)
        sub_thread.start()

    #7、关闭服务端套接字, 表示服务端以后不再等待接收客户端的连接请求
    # 因为服务端的程序需要一直运行,所以关闭服务端套接字的代码可以省略不写
    tcp_server_socket.close()


八、socket之send和recv原理剖析

8.1 TCP socket的发送和接收缓冲区

当创建一个TCP socke对象的时候会有一个发送缓冲区和一个接收缓冲区,这个发送和接收缓冲区指的是内存中的一个空间。

8.2 send原理剖析

必须通过网卡发送数据,需要调用操作系统接口,应用程序把发送的数据先写入发送缓冲区,由操作系统控制网卡把发送缓冲区的数据发送到服务端网卡

8.3 recv原理剖析

软件无法通过网卡接收数据,需要调用操作系统接口,由操作系统通过网卡接收数据,把接收的数据写入到接收缓冲区,应用程序再从接口缓存区获取客户端发送的数据

8.4 send和recv原理剖析图

在这里插入图片描述

说明:

  • 发送数据是发送到发送缓冲区
  • 接收数据是从接收缓冲区获取
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值