python基础之Socket套接字详解
作者:小马哥的班车 发布时间:2023-04-11 01:52:52
前言
Python语言提供了Socket套接字来实现网络通信。
Python的应用程序通常通过Socket"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。
服务器和客户端的源代码
服务器端
#coding=utf-8
#创建TCP服务器
import socket
import time
from time import ctime
HOST = '127.0.0.1'
PORT = 8080
BUFSIZE=1024
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(5)
addr=(HOST,PORT)
while True:
print('waiting for connection...')
sock,addr =sock.accept()
print('...connected from:',addr)
while True:
data =sock.recv(BUFSIZE).decode()
print('date=',data)
if not data:
break
sock.send(('[%s] %s' %(ctime(),data)).encode())
sock.close()
客户端
#coding=utf-8
#创建TCP客户端
import socket
HOST = '127.0.0.1'
PORT = 8080
BUFSIZE = 1024
ADDR=(HOST,PORT)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
while True:
data = input('> ')
if not data:
break
sock.send(data.encode())
data = sock.recv(BUFSIZE).decode()
if not data:
break
print(data)
sock.close()
执行结果显示:
首先执行服务器端,结果如图1:
紧接着执行客户端,如图2
需要注意的是:服务器端和客户端需要在两个IDLE Shell中打开,否则客户机一启动,服务器程序就会中止执行,而客户端又连不上服务器,从而报错,如图3
我们在图2中输入一些需要传输的信息,然后回车,在服务端可以看到收到了相关信息,如图4(客户端发送信息),图5(服务器端接收信息)
源代码解析
我们从服务器端开始看起,先上一部分代码:
import socket
import time
from time import ctime
这三句是导入了三个模块,分别是socket 模块、time模块和ctime模块。
1)socket 模块当中提供了与socket 套接字相关的各项功能,后面用到了很多,这里先介绍一个,其他一会再介绍:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
功能:创建套接字,并把创建好的套接字赋给一个变量sock,下面程序中与套接字相关的操作都由sock来完成。
格式:socket.socket([family[, type[, proto]]])
参数:
family: 套接字家族,可以使 AF_UNIX 或者 AF_INET。AF_INET,是指面向网络的,因特网;AF_UNIX,基于文件的;在本例中,我们使用AF_INET,利用因特网来进行通信。
type: 套接字类型,可以根据是面向连接的还是非连接分为 SOCK_STREAM 或 SOCK_DGRAM。
SOCK_STREAM:对应着TCP,提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。
SOCK_DGRAM:对应着UDP,提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。
本例中选TCP协议。
protocol: 一般不填默认为 0。
2)time模块,完成python中与时间相关的计算,例如time.sleep(5)延时5秒,time time() 返回当前时间的时间戳等等。
下面的ctime也是其中一个功能,函数把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式,可以便于我们观察。转换以后的格式如下:
print “time.ctime() : %s” % time.ctime()
结果:time.ctime() : Tue Feb 17 10:00:18 2013
在我们的例子中,图4的圈2所表示的就是转换后的时间。
HOST = '127.0.0.1'
PORT = 8080
BUFSIZE=1024
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(5)
addr=(HOST,PORT)
看完头部之后,我们来看第二部分。
前三句定义了三个变量:HOST、PORT、BUFSIZE,这三个变量分别是服务器的IP地址,服务器的端口,接收的最大数据量。
第四句sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 定义了socket 套接字。
第五句sock.bind((HOST, PORT)),将IP地址和端口绑定给定义的套接字sock。
第六句sock.listen(5),开始 TCP 监听。中间的5表示在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为 1,大部分应用程序设为 5 就可以了。
第七句addr=(HOST,PORT),定义了一个变量addr,并且将地址以元组的形式赋值给addr。
while True:
print('waiting for connection...')
sock,addr =sock.accept()
print('...connected from:',addr)
while True:
data =sock.recv(BUFSIZE).decode()
print('date=',data)
if not data:
break
sock.send(('[%s] %s' %(ctime(),data)).encode())
sock.close()
sock.close()
这是服务器代码的最后一部分,也是通信的主体,首先进入一个while True:的永真循环,进入之后执行print(‘waiting for connection…'),这就是图1上蓝色字所表示的一部分。
第三行执行sock,addr =sock.accept(),sock.accept()是被动接受TCP客户端连接,(阻塞式)等待连接的到来,当客户机启动提交请求后,服务器接受请求,并将客户端的IP地址等信息存入变量addr中。
第四行执行print('…connected from:',addr),所以输入字符串…connected from:以及客户端传来的IP地址和端口。
以上服务器和客户端的通信就连接起来了。
下面开始传送数据,又进入一个永真循环,代码:
while True:
data =sock.recv(BUFSIZE).decode()
print('date=',data)
if not data:
break
sock.send(('[%s] %s' %(ctime(),data)).encode())
sock.close()
第二行:data =sock.recv(BUFSIZE).decode()。
sock.recv()表示接收 TCP 数据,数据以字符串形式返回,BUFSIZE指定要接收的最大数据量。
decode() 将其他编码的字符串解码成unicode格式。
这里要说明一下,上图:
字符串在python内部是用unicode编码来表示,而在硬盘是utf-8格式。所以在存储和使用时要进行格式转换,转换的方式:
decode 将其他编码的字符串(例如utf-8)解码成unicode格式。
encode 将unicode编码成另一种编码格式(例如utf-8)。
当然decode和encode 不止可以转换utf-8类型,转换的类型可以通过 encoding 来指定,不过我们常用的就是这个。
总结一下,data =sock.recv(BUFSIZE).decode()执行结束就表示把客户端的数据接收过来存放到了data这个变量中。
下面进行第三行print(‘date=',data),打印数据,结果就是图5中的圈3所表示的。
第四行及第五行: 如果没有接收到数据,则跳出循环,继续监听。
if not data:
break
第六行 sock.send(('[%s] %s' %(ctime(),data)).encode()),向客户端发送转换格式(encode)后的数据。
数据包括两部分,第一部分是ctime(),表示以字符串形式表示的时间,data表示变量中存的信息.前面还有一部分'[%s] %s'中的%s格式化字符串,形成需要的输出格式。
最后一句sock.close(),关闭套接字。
这样服务器端就完成了。我们再来看客户端。
import socket
HOST = '127.0.0.1'
PORT = 8080
BUFSIZE = 1024
ADDR=(HOST,PORT)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
这部只解释几句,HOST = ‘127.0.0.1' ,PORT = 8080,这两句是服务器端的IP地址和端口号。
sock.connect((HOST, PORT)) 这一句是利用创建好的socket套接字主动初始化TCP服务器连接,就是向服务器提出申请,服务器端用sock.accept()接受请求。
这一句执行完之后,通信就建立起来了,在服务器端会执行print('…connected from:',addr),结果如图5圈2所示。
while True:
data = input('> ')
if not data:
break
sock.send(data.encode())
data = sock.recv(BUFSIZE).decode()
if not data:
break
print(data)
sock.close()
接下来进入永真循环,先是input函数,输出> 后等待输入,如图2所示。例如输入hi,server,如图4的圈1,然后后两句是
if not data:
break
如果没有输入,则跳出循环。
第五行sock.send(data.encode()),将输入的数据转换格式后将数据发送给服务器端,这时把hi,server发送给服务器端,服务器用data =sock.recv(BUFSIZE).decode()来接收,同时用print(‘date=',data)打印出来,结果如5的圈3所示。
这时,服务器会继续执行sock.send(('[%s] %s' %(ctime(),data)).encode()),把当前的时间和数据发送给客户端。
而在客户端,执行data = sock.recv(BUFSIZ).decode(),所以客户端会接收到相应的数据,并且打印出来,结果如图4的圈2所示。
来源:https://blog.csdn.net/drippingstone/article/details/115872734
猜你喜欢
- 1、单个关键字加亮代码: <div id="txt"> 用JS让文章内容指定
- 黑夜可能漫长,但总会迎来温暖的阳光,三月如期而至,武大的樱花又一次盛开。那么今天就一起来看看怎样在python中画一棵美丽的樱花树~说到用p
- 前言只有你想不到,没有我找不到写不了的好游戏!哈喽。我是你们的栗子同学啦~今天小编去了我朋友家里玩儿,看到了一个敲可爱的小狗狗,是我朋友养的
- json数据:[{"authenticate":-99,"last_ip":"156.2.
- 人丑就要多读书,颜值不够知识来凑,至少你可以用书籍来武装你的大脑,拯救你的人生。TIOBE编程语言排行榜前20的语言入门书籍推荐
- /* --注意:准备数据(可略过,非常耗时) CREATE TABLE CHECK1_T1 ( ID INT, C1 CHAR(8000)
- 由于ajax在跨域的访问上有问题,目前最好的方法是做代理.写了个代理程序和心得为了做ajax的代理,研究了下服务器端的xmlhttp并和客户
- python遍历迭代器自动链式处理数据pytorch.utils.data可兼容迭代数据训练处理,在dataloader中使用提高训练效率:
- 先简单说一下MP3的ID3 标记,因为主要是操作这个玩意MP3最开始的时候没有我们今天看到的那样,有歌手、年代,专集等等信息只有一些简单的参
- 最近收到一个朋友委托的需求,要将MP3的音频格式转换成wav的音频格式。于是,使用python写了这个小工具便于批量进行转换操作。首先,下载
- 前言圣诞节快到了,是不是想用python画一个可爱的圣诞树,我在各大网站都查了一下,都不太美观,然后我就学习了一下别人的代码改写了一下,自己
- 这个代码实现的是 手动点击起点 和 终点 ,程序自动判断距离、触屏时间 完成跳跃 原理(摘自
- 这个是作者自己封装的一个钉钉机器人的包,目前只支持发文本格式、链接格式、markdown格式的消息,我们可以在很多场景用到这个,比如告警通知
- 构筑专业的网络站点和应用程序,先进的设计工具,功能强大,开放式集成系统;流畅的开发进程。Macromedia Dreamweaver MX
- JavaScript中对象的property有三个属性:1.writable。该property是否可写。2.enumerable。当使用f
- 今天小编来和大家聊一下Python当中的altair可视化模块,并且通过调用该模块来绘制一些常见的图表,借助Altair,我们可以将更多的精
- (1)设计一个算法,确定两个矩形是否相交(即有重叠区域) (2)如果两个矩形相交,设计一个算法,求出相交的区域矩形 (1) 对于这个问题,一
- 在一篇文章 理解Python异步编程的基本原理 这篇文章中,我们讲到,如果在异步代码里面又包含了一段非常耗时的同步代码,异步代码就会被卡住。
- 目前python 提供了几种多线程实现方式 thread,threading,multithreading ,其中thread模块比较底层,
- 本文实例讲述了PHP实现的服务器一致性hash分布算法。分享给大家供大家参考,具体如下:<?php/** * 对服务器进行一致性has