-
2018-03-07 16:18:01
首先我们写一个客户端:
import socket # 客户端 发送一个数据,再接收一个数据 client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #声明socket类型,同时生成链接对象 client.connect(('localhost',6969)) #建立一个链接,连接到本地的6969端口 while True: msg = input('>>:').strip() #strip默认取出字符串的头尾空格 client.send(msg.encode('utf-8')) #发送一条信息 python3 只接收btye流 data = client.recv(1024) #接收一个信息,并指定接收的大小 为1024字节 print('recv:',data.decode()) #输出我接收的信息 client.close() #关闭这个链接
然后在写一个服务器端
我们这里的服务器端是可以接收多个链接的,当第一个链接没有断开时,后面的链接一直等待,知道第一个链接终止,才会链接第二个..链接,依此类推。
并且完美解决了error:10054的强制关闭服务器端的错误!import socket # 建立一个服务端 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(('localhost',6969)) #绑定要监听的端口 server.listen(5) #开始监听 表示可以使用五个链接排队 while True: # conn就是客户端链接过来而在服务端为期生成的一个链接实例 conn,addr = server.accept() #等待链接,多个链接的时候就会出现问题,其实返回了两个值 print(conn,addr) while True: try: data = conn.recv(1024) #接收数据 print('recv:',data.decode()) #打印接收到的数据 conn.send(data.upper()) #然后再发送数据 except ConnectionResetError as e: print('关闭了正在占线的链接!') break conn.close() server.close() #然后关闭服务
测试方法,先运行服务器端脚本,
然后运行客户端脚本,并发送信息,
再次打开运行一个客户端脚本,并发送信息。
会发现,会在等待第一个链接断开,当第一个链接断开的时候就会开启第二个链接,这里已经解决了当起一个链接断开的时候强制关闭服务器端。更多相关内容 -
python网络编程socket实现服务端、客户端操作详解
2021-01-20 01:44:04本文实例讲述了python网络编程socket实现服务端、客户端操作。分享给大家供大家参考,具体如下: 本文内容: socket介绍 TCP: 服务端 客户端 UDP: 服务端 客户端 首发时间:2018-02-08 01:14 修改: 2018-03... -
python网络编程之多线程同时接受和发送
2020-09-18 17:05:28主要为大家详细介绍了python网络编程之多线程同时接受和发送,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
python网络编程之socket
2022-01-09 18:00:05socket 为了保证数据的完整性和可靠性我们使用 tcp 传输协议进行数据的传输,udp是不管有没有建立连接成功都会进行发送,...负责进程之间的网络数据传输,只要跟网络相关的应用程序或者软件都使用到了 socket ...目录
socket
为了保证数据的完整性和可靠性我们使用 tcp 传输协议进行数据的传输,udp是不管有没有建立连接成功都会进行发送,如飞Q,邮件,为了能够找到对应设备我们需要使用 ip 地址,为了区别某个端口的应用程序接收数据我们需要使用端口号,那么通信数据是如何完成传输的呢?
使用 socket 来完成
负责进程之间的网络数据传输,只要跟网络相关的应用程序或者软件都使用到了 socket
TCP 网络应用程序开发分为:
- TCP 客户端程序开发
- TCP 服务端程序开发
客户端:
步骤说明:
- 创建客户端套接字对象
- 和服务端套接字建立连接
- 发送数据
- 接收数据
- 关闭客户端套接字
服务器
步骤说明:
- 创建服务端端套接字对象
- 绑定端口号
- 设置监听
- 等待接受客户端的连接请求
- 接收数据
- 发送数据
- 关闭套接字
导入 socket 模块 import socket
创建客户端 socket 对象
socket.socket(AddressFamily, Type)
参数说明:
- AddressFamily 表示IP地址类型, 分为TPv4和IPv6
- Type 表示传输协议类型
方法说明:
- connect((host, port)) 表示和服务端套接字建立连接, host是服务器ip地址,port是应用程序的端口号
- send(data) 表示发送数据,data是二进制数据
- recv(buffersize) 表示接收数据, buffersize是每次接收数据的长度
代码分析:
socket是遵循tcp/ip协议的,创建socket对象传入两参数,
并与服务器去建立连接 传入服务器ip port 元组
发送二进制数据,并编码
接收二进制数据并解码,
最后关闭socket,
一句话:socket对象与服务器连接后发送数据 或接收数据
import socket if __name__=='__main__': # 创建socket对象,并传入tcp/ip, # socket.AF_INET ipv4 # socket.SOCK_STREAM tcp tcp_client_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) tcp_client_socket.connect(('192.168.0.112',8989)) # 发送二进制数据 tcp_client_socket.send('你好'.encode('utf8')) # 接收二进制数据并解码 res=tcp_client_socket.recv(1024).decode('utf8') print('收到服务器的消息:',res) tcp_client_socket.close()
创建服务端 socket 对象
- bind((host, port)) 表示绑定端口号, host 是 ip 地址,port 是端口号,ip 地址一般不指定,表示本机的任何一个ip地址都可以。
- listen (backlog) 表示设置监听,backlog参数表示最大等待建立连接的个数。
- accept() 表示等待接受客户端的连接请求
- send(data) 表示发送数据,data 是二进制数据
- recv(buffersize) 表示接收数据, buffersize 是每次接收数据的长度
代码分析创建socket对象,
程序结束立即释放端口号
绑定端口号设置监听客户端连接的个数
等待客户端的连接,之后接收客户端的请求
import socket if __name__=='__main__': tcp_server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 程序退出端口号立即释放 tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True) # 绑定端口号 tcp_server_socket.bind(('',8989)) # 监听最多128个连接数 tcp_server_socket.listen(128) # 等待客户端的连接请求,只有连接后程序才会往下执行 # 建立连接后获取的2个参数 1和客户端通信的套接字,2客户端端口号 # 建立连接后TCP 服务器端程序会产生一个新的套接字,收发客户端消息使用该套接字 service_client_socket,ip_port=tcp_server_socket.accept() print(ip_port) # 接收客户端消息 recv_data=service_client_socket.recv(1024) #服务端可以通过返回数据的长度来判断客户端是否已经下线 recv_data_length=len(recv_data) recv_content=recv_data.decode('utf8') print(recv_content) send_data = "ok, 问题正在处理中...".encode("utf8") # 发送数据给客户端 service_client_socket.send(send_data) # 关闭服务与客户端的套接字, 终止和客户端通信的服务 service_client_socket.close() tcp_server_socket.close()
说明:
当客户端和服务端建立连接后,服务端程序退出后端口号不会立即释放,需要等待大概1-2分钟。
解决办法有两种:
- 更换服务端端口号
- 设置端口号复用(推荐大家使用),也就是说让服务端程序退出后端口号立即释放。
设置端口号复用的代码如下:
# 参数1: 表示当前套接字 # 参数2: 设置端口号复用选项 # 参数3: 设置端口号复用选项对应的值 tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
多线程服务器端
import socket import threading import time def handle_client_request(service_client_socket, ip_port): # 循环处理请求 while True: time.sleep(5) data=service_client_socket.recv(1024) # 若存在数据,即消息长度不是0 则打印 长度为0则客户端下线 if data: print('客户端发来的消息',data.decode('utf8'),'端口号',ip_port) # 特别注意:客户端服务端一旦连接,双方的收发必须一一对应,有发就有收,毕竟是基于TCP协议的, # 不然就成UDP协议的了 service_client_socket.send("ok,问题正在处理中...".encode("utf8")) else: print('客户端下线了') break service_client_socket.close() if __name__=='__main__': tcp_server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True) tcp_server_socket.bind(('',8989)) tcp_server_socket.listen(128) # 准备工作做完后循环执行 while True: # 等待接收客户端的连接请求 service_client_socket,ip_port=tcp_server_socket.accept() # 一旦走到这说明建立连接成功,连接后开启子线程完成多任务 #传入处理客户端请求的新socket和端口号 sub_t=threading.Thread(target=handle_client_request,args=(service_client_socket,ip_port),daemon=True) # 此时需要开启守护主线程,因为建立连接后才执行到子线程处理,此时若再子线程工作的时候客户端断开连接了 # 主线程无法正常断开连接 #分析:子线程执行需要5秒 再5秒内被客户端强制退出 导致子线程未执行完主线程就挂掉了 #Error 10054] 远程主机强迫关闭了一个现有的连接,要求子线程跟随主线程的生命周期 sub_t.start() # 这里不用关闭服务器socket 让其一直可以接收客户端发消息
socket之send和recv原理剖析
1. 认识TCP socket的发送和接收缓冲区
当创建一个TCP socket对象的时候会有一个发送缓冲区和一个接收缓冲区,这个发送和接收缓冲区指的就是内存中的一片空间。
2. send原理剖析
send是不是直接把数据发给服务端?
不是,要想发数据,必须得通过网卡发送数据,应用程序是无法直接通过网卡发送数据的,它需要调用操作系统接口,也就是说,应用程序把发送的数据先写入到发送缓冲区(内存中的一片空间),再由操作系统控制网卡把发送缓冲区的数据发送给服务端网卡 。
3. recv原理剖析
recv是不是直接从客户端接收数据?
不是,应用软件是无法直接通过网卡接收数据的,它需要调用操作系统接口,由操作系统通过网卡接收数据,把接收的数据写入到接收缓冲区(内存中的一片空间),应用程序再从接收缓存区获取客户端发送的数据。
4. send和recv原理剖析图
说明:
- 发送数据是发送到发送缓冲区
- 接收数据是从接收缓冲区 获取
-
python多线程socket编程之多客户端接入
2020-12-24 10:12:36Python中实现socket通信的服务端比较复杂,而客户端非常简单,所以客户端基本上都是用sockct模块...desc:socket编程客户端,python3.6.2 ''' import socket,sys HOST = '192.168.1.6' PORT = 8998 ADDR =(HOST,PORT) -
初学python网络编程socket,并实现文件传输【含源代码】
2020-05-18 20:06:49socket又称“套接字”, 应用程序通常通过“套接字”向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。 socket()函数 Python 中,我们用 socket()函数来创建套接字,语法格式如下: ...什么是Socket
socket又称“套接字”, 应用程序通常通过“套接字”向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。
socket()函数
Python 中,我们用 socket()函数来创建套接字,语法格式如下:
socket.socket(family, type, protocol)
参数: family: 套接字家族可以使AF_UNIX或者AF_INET
type:套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAM或SOCK_DGRAM
protocol: 一般不填默认为0.socket 对象内建方法
函数 描述
服务器端套接字:s.bind() 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。
s.listen() 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。
s.accept() 被动接受TCP客户端连接,(阻塞式)等待连接的到来 客户端套接字
s.connect() 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
公共用途的套接字函数
s.recv() 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
s.send() 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。
s.sendall() 完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
s.recvfrom() 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
s.sendto() 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。
s.close() 关闭套接字
s.getpeername() 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
s.getsockname() 返回套接字自己的地址。通常是一个元组(ipaddr,port)
s.setsockopt(level,optname,value) 设置给定套接字选项的值。
s.getsockopt(level,optname[.buflen]) 返回套接字选项的值。
s.settimeout(timeout) 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect())
s.gettimeout() 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。
s.fileno() 返回套接字的文件描述符。
s.setblocking(flag) 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。
s.makefile() 创建一个与该套接字相关连的文件
-----**** 上述来源于网络 ****-----------
实例:实现文件传输
实例演示:
服务器端打开
客户端运行,选择文件上传
客户端文件上传完毕
服务器端收到文件
注:本次演示不是在局域网上,而是在实际上的服务器上的文件传输演示
源代码:
客户端
""" author: 全洛 """ import socket import easygui as eg import json import os import time '''读取配置文件''' f = open('clientconf.json', 'r', encoding='utf-8') date = json.load(f) ip = date.get('IP') port = date.get('port') f.close() '''创建socket对象''' client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: '''连接服务器, 指定IP和端口''' client.connect((ip, port)) '''接收小于 1024 字节的数据''' msg = client.recv(1024) '''输出连接成功信息''' print(msg.decode('utf-8')) except Exception as e: print(f'连接服务器失败', e) else: '''选择发送的文件''' filepath = eg.fileopenbox(title='选择文件') '''获取文件名,文件大小''' filename = filepath.split("\\")[-1] filesize = os.path.getsize(filepath) # 先将文件名传过去 # 编码文件名 client.send(filename.encode()) time.sleep(0.5) # 再将将文件大小传过去 # 编码文件大小 client.send(filesize.to_bytes(filesize.bit_length(), byteorder='big')) try: '''传输文件''' start_time = time.time() with open(filepath, 'rb') as f: size = 0 while True: #读取文件数据,每次1024KB f_data = f.read(1024) # 数据长度不为零,传输继续 if f_data: client.send(f_data) size += len(f_data) if time.time() - start_time == 0: time.sleep(0.5) speed = (size) / (time.time() - start_time) print('\r' + '【上传进度】:%s%.2f%%, Speed: %.2fMB/s' % ('>' * int(size * 50 / filesize), float(size / filesize * 100), float(speed / 1024 / 1024)), end=' ') # 数据长度为零传输完成 else: print(f'{filename},{float(filesize/1024/1024):.2f}MB, 传输完成') break except Exception as e: print(f'传输异常', e) finally: '''关闭客户端''' client.close()
客户端配置:
{
“IP”: “182.92.112.155”,
“port”: 3636
}服务器端
""" author: 全洛 """ import socket import os import json import threading import time '''导入配置文件''' f = open('serverconf.json', 'r', encoding='utf-8') dirsave = json.load(f).get('dirSave') f.close() if not os.path.exists(dirsave): # 看是否有该文件夹,没有则创建文件夹 os.mkdir(dirsave) class server: def __init__(self): '''''' ''' 创建socket对象''' self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) '''获取本地''' self.host = socket.gethostname() '''设置端口''' self.port = 3636 '''绑定地址''' self.server.bind((self.host, self.port)) '''设置最大连接数, 超过后排队''' self.server.listen(12) print('服务器已上线\n等待客户端连接...\n') def server100(self): while True: '''建立客户端连接''' client, addr = self.server.accept() print(f'客户端: {str(addr)}, 连接上服务器') msg = f'已连接到服务器{self.host}!\r\n' client.send(msg.encode('utf-8')) # 有客户端连接后,创建一个线程给客户端 t1 = threading.Thread(self.taskfilethread(client)) # 设置线程守护 t1.setDaemon(True) # 启动线程 t1.start() def taskfilethread(self, client): '''接收文件名,文件大小''' filename = client.recv(1024) # time.sleep(0.5) filesize = client.recv(1024) # 解码文件名,文件大小 filename = filename.decode() filesize = int.from_bytes(filesize, byteorder='big') '''接收文件''' try: f = open(dirsave+"\\"+ filename, 'wb') size = 0 start_time = time.time() while True: # 接收数据 f_data = client.recv(1024) # 数据长度不为零,接收继续 if f_data: f.write(f_data) size += len(f_data) if time.time() - start_time == 0: time.sleep(0.5) speed = (size) / (time.time() - start_time) print('\r' + '【下载进度】:%s%.2f%%, Speed: %.2fMB/s' % ('>' * int(size * 50 / filesize), float(size / filesize * 100), float(speed/1024/1024)),end=' ') # 数据长度为零接收完成 else: break except Exception as e: print(f'接收异常', e) else: f.flush() print(f'{filename},{float(filesize/1024/1024):.2f}MB, 接收完成') f.close() if __name__ =='__main__': server = server() server.server100()
服务器端配置:
{
“dirSave”: “C:\Users\Administrator\Desktop\temp”
}
最后
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43347550/article/details/106199850
———————————————— -
Python socket网络编程TCP/IP服务器与客户端通信
2020-12-24 15:41:54Python socket网络编程 初学 python,前段时间买了两本书《python 编程从入门到实践》《Python 核心编程第三版》,第一本书主要讲的是一些基本语法和一些基本的使用方法,而第二本则深入很多,自己看来也是一知半解... -
python socket 网络编程
2019-01-19 10:30:03本代码主要是关于python socket 的网络编程,可以实现文件上传 文件下载 以及远程命令行的执行 -
Python 网络编程之UDP发送接收数据功能示例【基于socket套接字】
2020-09-18 13:57:42主要介绍了Python 网络编程之UDP发送接收数据功能,结合实例形式分析了Python使用socket套接字实现基于UDP协议的数据发送端与接收端相关操作技巧,需要的朋友可以参考下 -
详解Python Socket网络编程
2020-12-25 07:04:55Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要...本文主要介绍使用Python 进行TCP Socket 网络编程,假设你已经具有初步的网络知识及Python 基本语法知识。 TCP 是一种面向连接的传输层协议,TCP Sock -
python socket网络编程之粘包问题详解
2020-12-24 00:35:06一,粘包问题详情 ...若连续几次需要send的数据都很少,通常TCP socket 会根据优化算法把这些数据合成一个TCP段后一次发送出去,这样接收方就收到了粘包数据。 2,首先需要掌握一个socket收发消息的原理 发 -
python网络编程调用recv函数完整接收数据的三种方法
2020-12-24 07:50:49在使用socket进行网络编程中,如何判定对端发送一条报文是否接收完成,是进行socket网络开发必须要考虑的一个问题。这里,简要介绍一下判别数据接收接收完成常用的三种方法: 1.基础数据接收法: 使用基础数据接收法... -
python Socket网络编程实现C/S模式和P2P
2020-12-17 08:12:39由于网络课需要实现Socket网络编程,所以简单实现了一下,C/S模式分别用TCP/IP协议与UDP协议实现,下面将分别讲解。 TCP/IP协议 TCP/IP协议是面向连接的,即客户端与服务器需要先建立连接后才能传输数据,以下是... -
基于Python的网络编程实验报告.docx
2021-07-07 08:34:45一、实验目标: 掌握基于SOCKET的网络编程方法。 基于Python语言,编写一个网络应用程序。 二、实验内容 即时通信小程序(基于套接字)。 -
python之Socket网络编程详解
2020-12-23 13:23:57什么是网络? 网络是由节点和连线构成,表示诸多对象及其相互联系。在数学上,网络是一种图,一般认为专指加权图。网络除了数学定义外,还有具体的物理含义,即网络是从某种相同类型的实际问题中抽象出来的模型。在... -
python socket编程实例(服务端及客户端)
2018-05-23 10:53:24本代码是python实现的socket实例代码,包括客户端和服务端。 server.py为服务端。 client.py为客户端。 -
学习笔记(04):Python网络编程&并发编程-什么是socket
2021-01-06 11:26:03答:网络编程也叫做socket编程即套接字编程,基于遵循socket套接字的规定进行的编程 2.什么是socket? 答:socket就是一组简单的接口!socket抽象层位于TCP运输层和应用层之间,socket抽象层将TCP协议以及其他的协议... -
python socket 网络编程 教程
2013-10-16 14:52:49在本教程中,您将首先学习一些 Python的基础知识,并了解 Python 是如何成为一种很好的网络编程语言的。然后您将着重了解 Python 的基本 socket 特性,我们使用了一个样例聊天程序作为参考;并了解一下可以提供异步... -
Python网络编程(socket编程)
2018-05-13 14:28:38Win10python - 3.5 Socket工作原理和基本概念 Socket的中文翻译是套接字,它是TCP/IP网络环境下应用程序与底层通信驱动程序之间运行的开发接口,它可以将应用程序与具体的TCP/IP隔离开来,使得应用程序不需要了解...Win10
python - 3.5
Socket工作原理和基本概念
Socket的中文翻译是套接字,它是TCP/IP网络环境下应用程序与底层通信驱动程序之间运行的开发接口,它可以将应用程序与具体的TCP/IP隔离开来,使得应用程序不需要了解TCP/IP的具体细节,就能够实现数据传输。
在网络应用程序中,Socket通信是基于客户端/服务器结构。客户端是发送数据的一方。服务器时刻准备接受来自客户端的数据,对做出响应
实现基于tcp网络通信与现实中打电话很像:
1) 客户端(相当于打电话的一方),需要了解服务器的ip地址,如果该服务器有多个网络应用程序,单单ip地址则不够,这时候socket通信借用tcp/ip中端口的概念,不同应用程序使用不同端口通信(这就很类似电话分机)。
2) 服务器应用程序必须早于客户端启动,并在指定ip地址和端口上执行监听,端口被占用,服务器则无法正常启动。(服务器处于监听状态就类似电话接通好电话线,等待被拨打的状态)
3) 客户端在申请发送数据时,服务器端应用程序必须有足够的时间响应才能进行正常通信(电话响,却无人接听)。通常情况下,服务器的应用程序都需要具备同时处理多个客户端请求的能力,应用程序设计不合理或访问量过高都会导致响应超时。
4) 使用Socket协议进行通信的双方必须使用相同的通信协议,Socket支持的底层通信协议包括tcp和udp两种,通信过程中,双方还必须采用相同的字符编码,按照约定的方式进行通信(打电话时,双方必须语言相同,才能进行信息交流)
5) 通信时,物理网络必须保持通畅,否则通信将会中断(电话线有效,且连接正常)。
6) 通信结束之前,客户端和服务器端都可以中断连接(任何一方都可以挂电话)。
TCP是基于连接的通信协议,即先建立稳定连接后,再数据传输
如果Socket通信基于UDP,则数据传输前不需要连接,类似发短信或发电报,即使对方不在线,也可以发送数据,发送的数据在指定时间没有得到对方响应,则视为操作超时,可以选择超时后重新发送数据。
Socket编程的层次结构
应用层
Socket开发接口
传输层
TCP
UDP
网络层
IP
驱动
物理层
基于TCP的Socket编程
面向连接的Socket通信是基于TCP的
服务器程序要先与客户机程序启动,步骤以及调用函数:
1) 调用socket()函数创建一个流式套接字,返回套接字号s
2) 调用bind()将s绑定到已知地址,通常为本地ip
3) 调用listen()将s设为监听模式,准备接收来自各客户端的连接请求
4) 调用accept()等待接受客户端连接请求
5) 如果接收到客户端请求,则accept()返回,得到新的套接字ns
6) 调用rev()接收来自客户端的数据,调用send()向客户端发送数据
7) 与客户端通信结束,服务器端可以调用shutdown()对方不再接收和发送数据,也可以由客户端程序断开连接,断开连接后,服务器进程调用closesocket()关闭套接字ns,此后服务器返回第四步
8) 如果要退出服务器程序,则调用closesocket()关闭最初的套接字s
客户端程序步骤以及调用函数:
1) 调用WSAStartup()函数加载Windows Sockets动态库,然后调用socket()函数创建一个流式套接字,返回套接字号s。
2) 调用connect()函数将套接字s连接到服务器。
3) 调用send()函数向服务器发送数据,调用recv()函数接收来自服务器的数据。
4) 与服务器的通信结束后,客户端程序可以调用close()函数关闭套接字。
相关函数:
1.socket()函数
socket()函数用于创建与指定的服务提供者绑定套接字,函数原型如下:
socket=socket.socket(familly,type)
参数说明如下:
familly,指定协议的地址家族,可为AF_INET或AF_UNIX。AF_INET家族包括Internet地址,AF_UNIX家族用于同一台机器上的进程间通信。
type,指定套接字的类型。
套接字类型
说 明
SOCK_STREAM
提供顺序、可靠、双向和面向连接的字节流数据传输机制,使用TCP
SOCK_DGRAM
支持无连接的数据报,使用UDP
SOCK_RAW
原始套接字,可以用于接收本机网卡上的数据帧或者数据包
2.bind()函数
bind()函数可以将本地地址与一个Socket绑定在一起,函数原型如下:
socket.bind( address )
参数address是一个双元素元组,格式是(host,port)。host代表主机,port代表端口号。
3.listen()函数
listen()函数可以将套接字设置为监听接入连接的状态,函数原型如下:
listen(backlog);
参数backlog指定等待连接队列的最大长度。
4.accept()函数
在服务器端调用listen()函数监听接入连接后,可以调用accept()函数来等待接受连接请求。accept()的函数原型如下:
connection, address = socket.accept()
调用accept()方法后,socket会进入waiting状态。客户请求连接时,accept()方法会建立连接并返回服务器。accept()方法返回一个含有两个元素的元组(connection,address)。第一个元素connection是新的socket对象,服务器必须通过它与客户通信;第二个元素 address是客户的Internet地址。
5.recv()函数
调用recv()函数可以从已连接的Socket中接收数据。recv()的函数原型如下:
buf = sock.recv(size)
参数sock是接收数据的socket对象,参数size指定接收数据的缓冲区的大小。recv()的函数的返回接收的数据。
6.send()函数
调用send()函数可以在已连接的Socket上发送数据。send()的函数原型如下:
sock.recv(buf)
参数sock是在已连接的Socket上发送数据。参数buf是也要已连接的Socket上发送数据。
7.close()函数
close ()函数用于关闭一个Socket,释放其所占用的所有资源。socket()的函数原型如下:
s.closesocket();
参数s表示要关闭的Socket。
使用socket通讯的简易服务器
connection.close()import socket
if __name__ == "__main__":
#创建socket对象s,基于internet地址和tcp协议
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#绑定到本地的8001端口
s.bind(("localhost",8001))
#在本地8001端口监听,等待连接队列最大长度为5
s.listen(5)
print("等待连接")
while True:
#接收来自客户端的连接
connection,address = s.accept()
try:
connection.settimeout(5)
buf = connection.recv(1024).decode('utf-8')#接收客户端消息
if buf=='1':
connection.send(b'welcome to server')
else:
connection.send(b'please go out')
except s.timeout:
print('time out')
connection.close()使用socket进行通信的建议客户端
import socket
import time
if __name__ == '__main__':
s =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('localhost',8001))
#推迟执行
time.sleep(2)
s.send(b'1')
print(s.recv(1024).decode('utf-8'))
s.close()基于TCP的Socket编程
面向连接的Socket通信是基于TCP的由流程可以看出面向非连接的Socket通信流程比较简单,在服务器上不需要listen()和accept()来等待客户端连接,客户端程序不需要雨服务器建立连接,而是直接向服务器发送数据。
1. sendto()函数
使用sendto()函数可以实现发送数据的功能,函数原型如下;
s.sendto(data,(addr,port))
参数说明如下:
s,指定一个Socket句柄。
data,要传输数据。
addr,接收数据的计算机的IP地址。
port,接收数据的计算机的端口。
示例:import socket
#创建UDP SOCKET s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) port = 8000 #服务器端口 host = '192.168.0.101'#服务器地址 while True: msg = input()# 接受用户输入 if not msg: break # 发送数据 s.sendto(msg.encode(),(host,port)) s.close()
2. recvfrom()函数
使用recvfrom ()函数可以实现接收数据的功能,函数原型如下;
data,addr = s.recvfrom( bufsize);
参数说明如下:
s,指定一个Socket句柄。
bufsize,接收数据的缓冲区的长度,单位为字节。
data,接收数据的缓冲区。
addr,发送数据的客户端的地址。
示例:
import socket
#创建基于UDP的socket对象用socket.SOCK_DGRAM
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind(('localhost',8000))#循环调用recvfrom()接收客户端发送来的数据
while True:
data,addr = s.recvfrom(1024)
if not data:
print('client has exited!')
break
print('received:',data,'from',addr)
s.close()
-
python网络编程案例——五子棋游戏
2020-12-20 15:34:40网络五子棋游戏设计的难点在于对方进行通信,这里使用面向非连接的Socket编程,Socket编程用于C/S开发,在这类应用中,客户端和服务器端通常需要先建立连接,然后发送和接收数据,交互完成后需要断开连接,本章采用... -
python 网络编程socket
2016-10-09 15:31:29socket模块详解,通过这些基础知识可以使我们更好的理解网络编程。 一、网络知识的一些介绍 1、socket 是网络连接端点。 例说:当你的Web浏览器请求www.jb51.net上的主页时(即就是发送HTTP请求),web浏览器会创建... -
Python网络编程使用select实现socket全双工异步通信功能示例
2020-09-20 15:54:47主要介绍了Python网络编程使用select实现socket全双工异步通信功能,简单说明了select模块的功能及socket全双工异步通信功能的相关实现技巧,需要的朋友可以参考下 -
python网络编程实例简析
2020-12-24 18:16:09本文实例讲述了python网络编程,分享给大家供大家参考。 具体方法如下: 服务端代码如下: from SocketServer import(TCPServer as TCP, StreamRequestHandler as SRH) from time import ctime HOST = '' PORT = ... -
Python 网络编程之TCP客户端/服务端功能示例【基于socket套接字】
2020-09-18 14:01:35主要介绍了Python 网络编程之TCP客户端/服务端功能,结合实例形式分析了Python使用socket套接字实现TCP协议下的客户端与服务器端数据传输操作技巧,需要的朋友可以参考下 -
Python 网络编程起步(Socket发送消息)
2021-01-20 05:15:38import sockets = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 2. 绑定一个端口 s.bind((“”, 8081)) 3. 接受来自客户端的消息 while True: # Receive up to 1,024 bytes in a datagram ... -
python socket网络编程步骤详解(socket套接字使用)
2021-01-20 04:36:56一、套接字套接字是为特定网络协议(例如TCP/IP,ICMP/IP,UDP/IP等)套件对上的网络应用程序提供者提供当前可移植标准的对象。它们允许程序接受并进行连接,如发送和接受数据。为了建立通信通道,网络通信的每个... -
python网络socket基础练习
2022-03-24 21:15:08python网络socket基础练习 -
Python网络编程(Socket Tcp Udp)
2017-05-24 11:31:59建立网络通信连接至少要一对端口号(Socket),Socket本质是编程接口(API),对TCP/IP的封装,提供了网络通信能力。 每种服务都打开一个Socket,并绑定到端口上,不同的端口对应不同的服务,就像ht