最近看了一些socket编程,简单编写了一些客户端、服务端代码,希望可以给像我这样的初学者一些借鉴
一、实现TCP服务端
# -*- coding: utf-8 -*-
"""
Created on Wed Feb 20 13:36:14 2019
@author: Administrator
套接字练习1-创建TCP服务器
"""
import socket
from time import ctime
#socket.socket(socket_family, socket_type, protocol=0)函数用来创建套接字
#其中,socket_family是AF_UNIX或AF_INET(如前所述)
#socket_type是SOCK_STREAM 或 SOCK_DGRAM(也如前所述)
#protocol通常省略,默认为 0
#1.创建TCP/IP套接字
#tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#2.创建UDP/IP套接字
#udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#创建TCP服务器伪码
#ss = socket() # 创建服务器套接字
#ss.bind() # 套接字与地址绑定
#ss.listen() # 监听连接
#inf_loop: # 服务器无限循环
# cs = ss.accept() # 接受客户端连接
# comm_loop: # 通信循环
# cs.recv()/cs.send() # 对话(接收/发送)
# cs.close() # 关闭客户端套接字
#ss.close() # 关闭服务器套接字#(可选)
#1.TCP时间戳服务器:接受来自客户端的消息,然后将消息加上时间戳前缀返回给客户端
HOST='127.0.0.1' #设置服务器主机(与客户端使用同一个地址)
PORT=21564 #设置服务器端口号(与客户端使用同一个地址)
BUFSIZE=1024 #设置发送/接收的最大字节数
ADDR=(HOST,PORT)
tcp_socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建TCP套接字
tcp_socket.bind(ADDR) #将套接字绑定到服务器地址
tcp_socket.listen(5) #开启监听,listen() 方法的参数是在连接被转接或拒绝之前,传入连接请求的最大数
while True:
print('waiting for connection......')
tcp_client_socket,address=tcp_socket.accept() #返回元组,里面包含客户端socket->tcp_client_socket和地址address
print('...connected from:',address)
while True:
data=tcp_client_socket.recv(BUFSIZE)
if not data:
break
#接收之后先解码
data=data.decode('utf-8')
#按照给定要求拼装服务器返回样式
data='[%s] %s' % (bytes(ctime(),'utf-8'),data)
#发送之前要编码,增加编码转码,send需要的是byte类型的参数,此处为对数据类型的转换
data = data.encode("utf-8")
tcp_client_socket.send(data)
tcp_client_socket.close() #关闭客户端套接字
tcp_socket.close() #关闭服务端套接字
#总结:
#1.在运行程序时要注意,先运行服务器代码,后运行客户端代码
#2.在运行时可能会遇到OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次
# 这个原因是虽然把运行窗口中运行状态终结了,在执行的python程序实际上还没有结束,解决这个问题也简单,
# 打开windows任务管理器,把名为python的进程结束再重启就行了,如果你运行了好几个,那就把名为python的进程全部关掉。
#3.在运行程序时可能会遇到send() argument 1 must be string or buffer,not str 错误
# 此时需要对send的参数进行编码转码,例如上面写的:data = data.encode("ascii")
二、实现TCP客户端
# -*- coding: utf-8 -*-
"""
Created on Wed Feb 20 14:28:19 2019
@author: Administrator
套接字练习2-创建TCP客户端
"""
from socket import *
#TCP时间戳客户端
#创建TCP客户端伪码
#cs = socket() # 创建客户端套接字
#cs.connect() # 尝试连接服务器
#comm_loop: # 通信循环
# cs.send()/cs.recv() # 对话(发送/接收)
#cs.close() # 关闭客户端套接字
HOST='127.0.0.1'
PORT=21564
BUFSIZE=1024
ADDR=(HOST,PORT)
tcp_client_socket=socket(AF_INET, SOCK_STREAM) #创建客户端套接字
tcp_client_socket.connect(ADDR) #尝试连接服务器:当连接建立之后,它就可以参与到与服务器的一个对话中
while True:
data=input('please input something:')
#发送之前要编码,增加编码转码,send需要的是byte类型的参数,此处为对数据类型的转换
data = data.encode("utf-8")
#print(type(data))
if not data:
break
tcp_client_socket.send(data) #发送消息
data=tcp_client_socket.recv(BUFSIZE)
if not data:
break
#接受之后要解码
print(data.decode('utf-8'))
tcp_client_socket.close() #关闭客户端套接字
三、实现UDP服务端
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 21 09:12:45 2019
@author: Administrator
套接字练习3-创建UDP服务端
"""
from socket import *
from time import ctime
#创建TCP服务器伪码
#ss = socket() # 创建服务器套接字
#ss.bind() # 套接字与地址绑定
#inf_loop: # 服务器无限循环
# cs = ss.recvfrom()/ss.sendto() # 关闭(接收/发送)
#ss.close() # 关闭服务器套接字#(可选)
#1.UDP时间戳服务器:接受来自客户端的消息,然后将消息加上时间戳前缀返回给客户端
HOST='127.0.0.1' #设置服务器主机(与客户端使用同一个地址)
PORT=21566 #设置服务器端口号(与客户端使用同一个地址)
BUFSIZE=1024 #设置发送/接收的最大字节数
ADDR=(HOST,PORT)
udp_socket=socket(AF_INET, SOCK_DGRAM) #创建UDP套接字
udp_socket.bind(ADDR) #将套接字绑定到服务器地址
#udp_socket.listen(5) #开启监听,listen() 方法的参数是在连接被转接或拒绝之前,传入连接请求的最大数
while True:
print('waiting from message......')
data,address=udp_socket.recvfrom(BUFSIZE) #返回元组,里面包含客户端发送消息data和地址address
data=data.decode('utf-8')
#按照给定要求拼装服务器返回样式
data='[%s] %s' % (bytes(ctime(),'utf-8'),data)
#增加编码转码,sendto需要的是byte类型的参数,此处为对数据类型的转换
data = data.encode("utf-8")
udp_socket.sendto(data,address)
print('...received from and return to:',address)
udp_socket.close() #关闭服务端套接字
#总结:
#在python3中,利用套接字传输的内容都以byte形式传输,这时候传送时(send/sendto)需要encode,
#接收(recv)时需要decode。编码与解码的形式要一致,本例中全部使用“utf-8”
四、实现UDP客户端
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 21 09:27:30 2019
@author: Administrator
套接字练习4-创建UDP客户端
"""
from socket import *
#UDP时间戳客户端
#创建UDP客户端伪码
#cs = socket() # 创建客户端套接字
#comm_loop: # 通信循环
# cs.sendto()/cs.recvfrom() # 对话(发送/接收)
#cs.close() # 关闭客户端套接字
HOST='127.0.0.1'
PORT=21566
BUFSIZE=1024
ADDR=(HOST,PORT)
udp_client_socket=socket(AF_INET, SOCK_DGRAM) #创建客户端套接字
while True:
data=input('please input something:')
#增加编码转码,sendto需要的是byte类型的参数,此处为对数据类型的转换
data = data.encode("utf-8")
#print(type(data))
if not data: #data为空
break
udp_client_socket.sendto(data,ADDR) #发送数据,参数包含数据消息与服务器地址和端口号
data,ADDR=udp_client_socket.recvfrom(BUFSIZE) #接收服务器消息
data = data.decode("utf-8")
if not data:
break
print(data)
udp_client_socket.close()