socket



# socket 是一套接口,封装了网络编程协议
socket是位于应用层与传输层之间的一个抽象层
专门把传输层以下的协议封装成接口提供给应用层使用
应用只需要调用socket的接口或者说按照socket的标准编写
程序,写出的程序自然是遵循tcp/ip协议


1, #===================================server.py

import
socket #作为服务器必须明确自己的IP和端口号,并且不应该改变 #参数1 指定socket类型 socket.AF_INET 表示网络类型 #参数2 指定的传输协议为 socket.SOCK_STREAM 表示为TCP协议 socket.SOCK_DGRAM协议表示UDP协议 # server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #1,买电话机 #默认是网络类型 TCP协议 server = socket.socket() #127.0.0.1 这叫回送地址 表示当前电脑本身 # ip 一定是本机IP 本机可能会有多个IP(无线|有线) #注意:需要参数就是一个元组,端口就是普通参数 server.bind(('127.0.0.1',8989)) #2,插入手机卡 #无论是服务器还是客户端 , 都是socket类型 #开始监听1688端口 盯着这个端口看以后没有数据过去 server.listen(4) #3,手机开始待机 #接受链接请求 #第一个表示客户端的socket 第二个客户端的地址信息 cilent,add = server.accept() #4,接电话 #5,收发数据 data = cilent.recv(1024) print(data.decode('utf-8')) cilent.send('你好,我是服务端!'.encode('utf-8')) server.close()
#=================================client.py import socket #买个电话 cilent = socket.socket() # 作为客户端 ip 和端口可以变化,所有系统会自动分配随机端口给客户端 cilent.connect(('127.0.0.1',8989)) #开始通话 #发送数据,注意发送的内容只能是二进制 bytes cilent.send('hello ,我是客户端'.encode('utf-8')) #接收数据 单位为字节 data = cilent.recv(1024) print(data.decode('utf-8')) cilent.close()
2 ,#==========================client.py

import
socket client = socket.socket() #connect 本质实在进行三次握手,也是一个数据传输的过程,如果服务器没有立马响应,也会阻塞 client.connect(('127.0.0.1',8989)) #三次握手 print('握手成功! client') #发送数据,本质是把数据交给操作系统来进行发送,一旦数据交给了操作系统,后续的发送 #应用程序就无法控制了,send一般不会卡,当然,如果数据很大就会阻塞 client.send('hello'.encode('utf-8')) print('发送完成') #是从操作系统缓存区读取数据,如果当前还没有任何数据,就会进入阻塞 #会一直等到有数据到来,在继续执行 try: data = client.recv(1024) print('接受完成') print(data) except: print('服务器 强行下线了') import time time.sleep(4) #客户端执行close是正常关闭链接,会给服务器送空字节,用于表示要断开链接 client.close() print('客户端关机了')
#==========================server.py import socket server = socket.socket() server.bind(('127.0.0.1',8989)) #只有服务器需要绑定 server.listen(4) #accept 是一个阻塞函数 会一直等到有客户端链接过来,在继续执行 cilent,addr = server.accept() #完成了三次握手 print(cilent,addr) #('127.0.0.1', 61638) print('握手成功!') #收发数据 注意都是用表示客户端的socket来收发数据 cilent.send('world'.encode('utf-8')) import time time.sleep(3) try: data = cilent.recv(1024) print('客户端发来的数据',data) #发送数据时,对方可能也会异常下线,也会抛出异常 #接受数据和发送数据都应该放到try cilent.send('test'.encode('utf-8')) except: print('cilent 下线了') #断开链接 cilent.close() #完成四次挥手 server.close() print("服务器关机!")
3 ,加上循环 #=========================client.py

import
socket client = socket.socket() #指定服务器的端口和ip 客户端的端口系统会自动分配 client.connect(('127.0.0.1',8989)) #添加循环,用来重复接收数据 while True: #收发的顺序 必须和对面相反,否则会卡死 msg = input('输入内容:') if not msg:continue #发送信息 client.send(msg.encode('utf-8')) print('发送%s完成!'%msg) #接收信息 data = client.recv(1024) print('接收到:%s'%data.decode('utf-8')) client.close() #=====================================server.py import socket server = socket.socket() server.bind(('127.0.0.1',8989)) server.listen(5) while True: client_socket,client_addr = server.accept() buffer_size = 1024 #缓冲区 就是一个临时的容器 #缓冲区大小 不能随便写,太大会导致内存溢出 ,太小效率低下,在内存能够承受的情况下,可以打一些 while True: try: #接收数据 data =client_socket.recv(1024) #在linux中,对方如果强行下线了,服务器不会抛出异常,只会收到空消息 #得加上以下判断,如果为空则意味着 对方下线了,应该关闭链接,跳出循环 #windows上如果输入Q正常关闭,也会收到空消息不会抛异常会一直循环空,所有if必须要加 if not data: client_socket.close() break print('接收到%s'%data.decode('utf-8')) #解码时必须保证双方统一编码方式 #发送数据,转为大写在发回去 client_socket.send(data.upper()) except ConnectionResetError as e: print('%s %s'%(client_addr[0],client_addr[1]),e) #如果对方下线了,那服务器也应该关闭对应的客户端对象 client_socket.close() break #通常服务器不会关闭 # server.close()
4 ,加上异常 #==============================client.py

import
socket client = socket.socket() #connect 本质实在进行三次握手,也是一个数据传输的过程,如果服务器没有立马响应,也会阻塞 client.connect(('127.0.0.1',8989)) #三次握手 print('握手成功! client') #发送数据,本质是把数据交给操作系统来进行发送,一旦数据交给了操作系统,后续的发送 #应用程序就无法控制了,send一般不会卡,当然,如果数据很大就会阻塞 client.send('hello'.encode('utf-8')) print('发送完成') #是从操作系统缓存区读取数据,如果当前还没有任何数据,就会进入阻塞 #会一直等到有数据到来,在继续执行 try: data = client.recv(1024) print('接受完成') print(data) except: print('服务器 强行下线了') import time time.sleep(4) #客户端执行close是正常关闭链接,会给服务器送空字节,用于表示要断开链接 client.close() print('客户端关机了') #==================================server.py import socket server = socket.socket() server.bind(('127.0.0.1',8989)) #只有服务器需要绑定 server.listen(4) #accept 是一个阻塞函数 会一直等到有客户端链接过来,在继续执行 cilent,addr = server.accept() #完成了三次握手 print(cilent,addr) #('127.0.0.1', 61638) print('握手成功!') #收发数据 注意都是用表示客户端的socket来收发数据 cilent.send('world'.encode('utf-8')) import time time.sleep(3) try: data = cilent.recv(1024) print('客户端发来的数据',data) #发送数据时,对方可能也会异常下线,也会抛出异常 #接受数据和发送数据都应该放到try cilent.send('test'.encode('utf-8')) except: print('cilent 下线了') #断开链接 cilent.close() #完成四次挥手 server.close() print("服务器关机!")

5, 端口占用问题:=============================server.py

import
socket server = socket.socket() server.bind(('127.0.0.1',9090)) server.listen() server.accept() server.close() #如果已经开启了服务器,再次运行将会抛出端口占用异常,把之前开启的服务器关掉即可 ''' 有些情况 明明关闭了进程,但是还是端口占用 可能是进程正在后台运行,可以通过端口查出进程,进行关闭 解决方式一 : 杀进程 windows下 netstat -ano| findstr 9090 tasklist | findstr 进程id 拿到进程名称 taskkill /f /t /im 进程名称 解决方式二: 重启电脑 '''