小工具      在线工具  汉语词典  dos游戏  css  js  c++  java

python网络编程与使用TCP协议实现聊天室

Python,python,tcp,udp,网络协议,网络 额外说明

收录于:17天前

网络编程

从广义上讲,网络编程就是信息的发送和接收,中间传输就是物理线路的作用。

网络编程的主要任务是在发送端通过规定的协议将信息组装成数据包,并在接收端根据规定的协议解析数据包,提取相应的信息,达到通信的目的。中间最重要的是数据包的组装、数据包的过滤、数据包的捕获、数据包的分析,当然还有一些最后的处理,比如代码、开发工具、数据库、服务器设置,以及网页设计。

套接字是网络通信的关键。套接字也是应用程序和网络协议之间的接口。套接字由 IP 和端口号组成。

网络层通信主要由两种通信协议组成:TCP和UDP。数据传输的基本单位是数据包。网络层通信的关键是通过网络应用程序发送网络层协议封装的数据包,从而使计算机能够进行通信。

Socket

套接字是一个对象,它为特定网络协议(如 TCP/IP、ICMP/IP、UDP/IP 等)套件对上的网络应用程序提供者提供当前的可移植标准。它们允许程序接受并建立连接,例如发送和接收数据。为了建立通信通道,网络通信的每个端点都拥有一个套接字对象是极其重要的。

Socket是应用层和TCP/IP协议族之间进行通信的中间软件抽象层。它是一组接口。在设计模式上,Socket实际上是一种门面模式,将复杂的TCP/IP协议族隐藏在Socket接口的背后。对于用户来说,一组简单的接口就够了,让Socket组织数据来满足指定的需求。协议。因此,我们不需要深入了解TCP/UDP协议。套接字已经为我们封装好了。我们只需要按照socket的规定来编程即可。我们写的程序自然会遵循TCP/UDP标准。

在这里插入图片描述
一般socket建立链接需要六个步骤,其中包括:socket.socket()创建socket对象、s.bind绑定地址到socket对象、s.listen监听地址端口、s.accept阻塞接受链接请求、s.send,s.recv方法处理通信数据、s.close关闭链接。

python scoket

Python 提供了两种级别的网络服务访问:

低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统 Socket 接口的全部方法。
高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。

Python 中,我们用socket库的 socket()函数来创建套接字,语法格式如下:
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
参数:
socket.socket(socket.AF_INET,socket.SOCK_STREAM)使用给定的地址族,套接字类型和协议号来创建一个新套接字。

family为指定的地址族:

socket.AF_UNIX:只能够用于单一的Unix系统进程间通信

socket.AF_INET:服务器之间的网络通信(ipv4协议的TCP和UDP)ipv4,默认为这个

socket.AF_INET6:服务器之间的网络通信ipv6

type为指定的套接字类型:

socket.SOCK_STREAM :面向连接的TCP,默认为这个

socket.SOCK_DGRAM:面向非连接的UDP

套接字API
socket.scoket(…)可以创建一个scoket对象,socket对象只是一个TCP或UDP数据包的装载对象,主机通过该对象发送数据包。因此通讯的双方都需要socket对象。一方作为数据的接收端服务端,一方作为数据的发送端客户端。socket对象提供了API来创建服务端和客户端程序。

方法 描述
服务器API 服务器端套接字
套接字.bind() 将地址(主机、端口)绑定到套接字。在AF_INET下,地址以元组(主机,端口)的形式表示。用于服务器,绑定监听端口,可以使用0.0.0.0接收所有IP,127.0.0.0只接受本地服务。
套接字.listen() 启动 TCP 监听。该参数指定操作系统在拒绝连接之前可以挂起的最大连接数。该值必须至少为1,大多数应用程序可以设置为5,这是服务器端程序。
套接字.accept() 被动接受TCP客户端连接,(阻塞式)等待连接的到来,没有来自客户端的请求是处于阻塞状态。accept方法会返回一个含有两个元素的元组,(fd,addr)fd, addr = self._accept() 。第一个元素是新的socket对象,服务器通过它与客户端通信。第二个元素是客户端的地址及端口信息。
客户端API 客户端套接字
套接字.connect() 主动初始化TCP服务器连接。参数格式是一个元组(主机名,端口)。如果发生连接错误,则返回socket.error错误。元组的第一个参数是ip,可以是ip,也可以是域名。第一个数字是端口号,即套接字。
套接字.connect_ex() connect() 函数的扩展版本,在发生错误时返回错误代码而不是引发异常。
公共API 公用套接字函数
套接字.recv() 接收TCP数据。数据以字符串的形式返回。有两个参数。 bufsize 指定要接收的最大数据量。 flag 提供有关消息的附加信息,通常可以忽略。
套接字.send() 发送 TCP 数据,将参数作为封装的 TCP 数据包发送到连接的套接字。返回值是要发送的字节数。参数只能是字节。其他类型是高级语言所特有的,无法被计算机解析。只有将其他类型转换为字节编码('utf-8')才能发送。
套接字.sendall() 完整发送TCP数据,完整发送TCP数据。将字符串中的数据发送到连接的套接字,但在返回之前尝试发送所有数据。成功时返回 None,失败时抛出异常。
socket.recvfrom() 接收UDP数据,与recv()类似,但返回值为(data,address)。其中data是包含接收到的数据的字符串,address是数据发送到的套接字地址。创建套接字时类型参数必须对应。
套接字.sendto() 将 UDP 数据发送到套接字,其中地址是指定远程地址的 (ipaddr, port) 形式的元组。返回值是发送的字节数。
套接字.close() 关闭套接字
套接字.getpeername() 返回连接套接字的远程地址。返回值通常是一个元组(ipaddr,端口)
socket.getsockname() 返回套接字自己的地址。通常是一个元组(ipaddr,端口)
socket.setsockopt(级别,optname,值) 设置给定套接字选项的值
socket.getsockopt(级别,optname[.buflen]) 返回套接字选项的值。
socket.settimeout(超时) 设置socket操作的超时时间。超时是一个以秒为单位的浮点数。 None 值表示没有超时时间。一般来说,超时应该在第一次创建套接字时设置,因为它们可能用于连接操作(例如 connect())
套接字.gettimeout() 返回当前超时时间的值(以秒为单位)。如果没有设置超时时间,则返回None。
套接字.fileno() 返回套接字的文件描述符
socket.setblocking(标志) 如果flag为0,则将套接字设置为非阻塞模式,否则将套接字设置为阻塞模式(默认)。在非阻塞模式下,如果调用recv()没有找到数据,或者调用send()无法立即发送数据,则会引发socket.error异常。
套接字.makefile() 创建与套接字关联的文件

简单TCP案例
服务端:

import socket

# 创建socket,网络协议为ipv4,网络层协议为TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定套接字,接收所有ip
s.bind(('0.0.0.0',9000))

# 监听端口,指定连接最大数量
s.listen(2)
print("is listening...")

# 等待客户端连接,返回服务端scoket连接和套接字
fd, addr = s.accept()
print("connect to client successful")

# 接收客户端数据
data = fd.recv(1024)
print(data)

# 响应客户端
fd.send("Welcome to connect !".encode("utf-8"))

# 关闭连接
s.close()
print("closed")

客户:

import socket

# 创建socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 建立连接
s.connect(("127.0.0.1",9000))

# 发送数据
s.send("hello".encode("utf-8"))
print("connect to server successful")

# 接收响应数据
data = s.recv(1024)
print(data.decode("utf-8"))

# 关闭连接
s.close()
print("closed")

TCP协议的三次握手建立连接,所以第一次必须由客户端发送连接请求,因此服务端必须要在客户端先开启服务。

服务端运行结果:
在这里插入图片描述

客户端运行结果:
在这里插入图片描述

python聊天室

服务器端程序

import socket

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

s.bind(('0.0.0.0', 9000))

s.listen(1)
print("is listening...")

fd, addr = s.accept()
print(fd.getpeername(), "is connected")
fd.send("welcome to connect !".encode('utf-8'))


def send_msg():
    print("请输入:")
    data0 = input()
    fd.send(data0.encode("utf-8"))


def recv_meg():
    data1 = fd.recv(1024)
    print("收到客户端消息:", data1)


if __name__ == "__main__":
    while True:
        # 接收消息
        recv_meg()
        # 发送消息
        send_msg()
        print("已发送")

客户程序

import socket

s = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
s.connect(('127.0.0.1', 9000))
print("连接成功!")


def make_sock():
    send_data=input()
    s.send(send_data.encode("utf-8"))
    print("已发送!")
    return None


def recv_scok():
    get_data = s.recv(1024)
    if get_data is None:
        print("未收到数据")
    else:
        print("收到服务端内容:")
        print(get_data)
    return None


if __name__ == "__main__":
    flag = 1
    while True:
        if flag == 0:
            s.close()
            break
        else:
            print("请输入:")
            make_sock()
        # 接收消息
        recv_scok()
        print("请选择:任意.继续聊天 0.退出")
        a = input()
        flag = a



在这里插入图片描述

参考资料:
https://www.cnblogs.com/yunlong-study/p/9283529.html
https://www.cnblogs.com/zhangyingai/p/7097922.html
https://www.cnblogs.com/zhangxinqi/p/8243919.html
http://www.runoob.com/python3/python3-socket.html

UDP协议
udp和tcp差不多,只是udp使无连接无状态的,不需要监听,只有接收和发送数据。可能造成数据丢失。

# 客户端
import socket

s = socket.socket(family=socket.AF_INET,type=socket.SOCK_DGRAM)

# 发送数据
s.sendto("hell0".encode("utf-8"),('127.0.0.1',9000))
# 接收数据
data = s.recv(1024)
print(data)

if __name__ == "__main__":
    while True:
        print("请输入:")
        put = input()
        s.sendto(put.encode("utf-8"),('127.0.0.1',9000))
        print("收到服务端的数据:",s.recvfrom(1024))
# 服务器端

import socket

s = socket.socket(family=socket.AF_INET,type=socket.SOCK_DGRAM)

# 绑定端口
s.bind(("127.0.0.1",9000))

# 接收数据
data = s.recvfrom(1024)
print("收到来自客户端消息:",data)

# 发送数据
s.sendto("send a message to you".encode("utf-8"),('127.0.0.1',9000))

if __name__ == "__main__":
    while True:
        print("请输入:")
        put = input()
        s.sendto(put.encode("utf-8"),('127.0.0.1',9000))
        print("收到客户端的数据:",s.recvfrom(1024))

udp协议程序只管发送和接收数据,如果接收端没有udp程序接收数据就丢失了。
在这里插入图片描述

在主机上测试,发送端是自己,接收端也是省内,客户端的Qi激活,数据全部在服务器上。

. . .

相关推荐

额外说明

前后端分离的情况下,全局字体格式如何设置?

目录 1、创建 font 文件夹 2、创建 font.css文件 3、全局注册 4、全局使用 1、创建 font 文件夹

额外说明

每日一题:Leetcode977 有序数组的平方

文章目录 系列:数组专练 语言:java 题目来源:leetcode977 有序数组的平方 难度:简单 考点:双指针的应用 & 暴力法的理解 思路和参考答案 文章目录 题目描述 一、思路 二、参考代码 题目描述 给你一个按 非递减顺序 排序的整数数组 n

额外说明

ES6变量的解构赋值

1.数组解构         1.1第一种方法解构 let [arry1, arry2, arry3] = [1, 2, 3] //依次提取 console.log(arry1); //1 console.log(

额外说明

二战MySQL数据库【升华篇】

MYSQL入门系列——第二篇 每篇前言: 1.筛选条件: (1)比较运算符: (2)逻辑运算符: (3)其他操作: 1.排序: 2.限制: 拓展: 3.去重: 4.模糊查询: (like '%') 5.范围查询: 2.聚合与分组(重点哦!): (1)常用

额外说明

【算法系列篇】双指针

文章目录 前言 什么是双指针算法 1.移动零 1.1 题目要求 1.2 做题思路 1.3 Java代码实现 2.复写零 2.1 题目要求 2.2 做题思路 2.3 Java代码实现 3.快乐数 3.1 题目要求 3.2 做题思路 3.3 Java代码实现

额外说明

大数据环境搭建 —— VMware Workstation 安装详细教程

大数据系列文章:- 目录 - 文章目录 一、下载安装包 1. 下载 VMware Workstation 2. 小技巧 二、安装软件 1. 软件安装 2. 虚拟环境搭建 一、下载安装包 1. 下载 VMware Workstation ① 打开 VMwa

额外说明

用PHP实现经典的5种排序算法

文章目录 一、前言 二、5种排序算法 2.1 快速排序 2.2 插入排序 2.3 选择排序 2.4 冒泡排序 2.5 归并排序 总结 一、前言 排序算法是一种将一组无序的数据元素按照某个规则(大小、字母序等)排列成有序的序列的算法。常见的排序算法包括冒泡

额外说明

Spring Boot基础学习笔记:可视化数据

文章目录 一、提出任务 (一)班级数据 (二)运行效果 二、实现步骤 (一)创建数据库与表 1、创建数据库 - test 2、创建数据表 - t_class (二)创建Spring Boot项目 - EChartsDemo (三)创建班级实体类 - Cl

额外说明

解决Cannot format given Object as a Number问题,理解DecimalFormat.format()方法及使用DecimalFormat保留两位小数的金额和格式化数字

目录 问题 解释DecimalFormat 复现问题 解决问题 总结 问题 今天在编程时,产品经理突然和我说,把所有的金额保留两位小数后,传递到前台。一时间,不知道该怎么做,于是,通过百度百科,查找到了DecimalFormat这个类。 解释Decima

额外说明

SQL SERVER优化建议

SQL SERVER优化建议 在 实际的工作中,尤其是在生产环境里边,SQL语句的优化问题十分的重要,它对数据库的性能的提升也起着显著的作用.我们总是在抱怨机器的性能问题,总是在 抱怨并发访问所带来的琐问题,但是如果我们对没一条SQL语句进行优化,尽管不

ads via 小工具