【例1】远程数据通信示例,本例由客户端程序和服务器程序两部分组成。





应用实例:与机器聊天
# -*- coding:utf-8 -*-
# 服务器端程序 hx02Server.py
import socket #导入socket模块
ms=["Hi,我是HX小信 !","很高兴与您聊聊,相互认识!你叫什么名?","在哪个学校读书?","我在华夏学院读书,学计算机专业","我在学Python程序设计。 ","学程序设计很有意思!",
"好好学习,天天向上!这是毛主席语录。","广州是广东省省城,很美!","广州从化区有全国著名的温泉!很好玩!", "厚德载物!这名言是清华大学的校训。",
"阅读使人充实,会谈使人敏捷,写作使人精确。这是培根的名言。","培根是英国文艺复兴时期最重要的散作家、哲学家。",
"厚德、重能、敬业、善事!这是华夏学院校训。" ,"华夏真的很美!"," 欢迎你来到华夏!","我爱信工学院,我想您也是的!","信工学院欢迎您!"]
try:
s = socket.socket() #创建 socket 对象
host ='127.0.0.1' # host=socket.gethostname() #主机IP host = '127.0.0.1'
port =8080 #端口号 如:8080
s.bind((host, port))
s.listen(10) #设置最多连接数
print(host," 服务器在监听,等待客户端连接... \n")
k=0
while True: #开启永真循环
c= s.accept()[0] #建立客户端连接
d=c.recv(1024) #获取客户端请求数据
d=d.decode() #将接收的数据模式转换
t=c
print(t,type(t))
print('\n',t,'发来信息:\n ',d) #打印输出接受数据
d=ms[k]+"\n "
k=k+1
d=d.encode()
c.send(d) # 向客户端发送数据
if k%16==0: break
c.close()
s.close()
except Exception as e:
print('\n',e)
print("服务器工作结束! BYE- BYE! ")
s.close() #关闭链接
c.close()
# 客户端程序 hx02Client
import socket # 导入socket模块
def sends():
s= socket.socket() # 创建TCP/IP套接字
host = '127.0.0.1' # 获取主机地址
port = 8080 # 设置端口号
s.connect((host,port)) # 主动初始化TCP服务器连接
send_data = input("请说:") # 提示用户输入数据
s.send(send_data.encode()) # 发送TCP数据
# 接收对方发送过来的数据,最大接收1024个字节
recvData = s.recv(1024).decode()
#print('接收到的回应信息:',recvData)
# 关闭套接字
s.close()
return recvData
k=0
while True:
datas=sends()
k=k+1
print('对方回应: \n',datas)
if k%16==0 :
print("就聊到此吧,你真棒!@@ BYE- BYE! ")
break
(二)基于UDP协议的网络程序设计
UDP协议是面向无连接的协议。使用UDP协议时,不需要建立链接,只需要知道对方的IP地址和端口号,就可以直接发数据包。
UDP协议的编写步骤
创建socket套接字
发送/接收数据
关闭套接字
【例2】编写程序,实现下列功能:
1.一台客户机从键盘输入一行字符,并通过其套接字将该行发送到服务器。
2.服务器从其连接套接字读取字符。
3.服务器将该行字符转换成大写。
4.服务器将修改后的字符串(行)通过连接套接字再发回给客户机。
5.客户机从其套接字中读取修改后的行,然后将该行在监视器上打印出来。
(1)服务器端
import socket
#创建一个socket,SOCK_DGRAM表示UDP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('127.0.0.1', 10021)) # 绑定IP地址及端口
print('Bound UDP on 10021...')
while True:
# 获得数据和客户端的地址与端口,一次最大接收1024字节
data, addr = s.recvfrom(1024) print('Received from %s:%s.' % addr)
# 将数据变成大写送回客户端
s.sendto(data.decode('utf-8').upper().encode(), addr)
# 不关闭socket

(2)客户机端
#coding=utf-8
from socket import *
# 1. 创建udp套接字
udp_socket = socket(AF_INET, SOCK_DGRAM)
# 2. 准备接收方的地址
# '192.168.1.103'表示目的ip地址
# 10021表示目的端口
dest_addr = ('127.0.0.1', 10021) # 地址为元组,ip是字符串,端口是数字
while True:
# 3. 从键盘获取数据
send_data = input("请输入要发送的数据:")
if not send_data or send_data == 'quit':
break
# 4. 发送数据到指定的电脑上的指定程序中
udp_socket.sendto(send_data.encode('utf-8'), dest_addr)
# 5. 等待接收对方发送的数据
# 如果没有收到数据则会阻塞等待 直到收到数据
recv_data = udp_socket.recvfrom(1024) # 1024表示本次接收的最大字节数
# 6. 显示对方发送的数据
# 接收到的数据recv_data是一个元组
# 第1个元素是对方发送的数据
# 第2个元素是对方的ip和端口
print(recv_data[0].decode('utf-8') , recv_data[1])
# 5. 关闭套接字
udp_socket.close()
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.recv() | 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。 |
s.send() | 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。 |
s.sendall() | 完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。 |
s.recvfrom() | 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。 |
s.sendto() | 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。 |
s.close() | 关闭套接字 |

