在网络编程中,socket编程是一门必须掌握的技能。通过socket编程,我们可以实现进程间的通信,也可以实现不同计算机间的数据传输。本文将分享一个基于socket编程的实例案例,供大家学习和实践。
实例案例:简单的聊天程序
在这个实例中,我们将创建一个简单的聊天程序,可实现两台计算机间的通信。一台计算机将作为服务器端,另一台计算机将作为客户端。服务器端将等待客户端连接,接受客户端发送的消息,并将其广播给所有连接的客户端。而客户端将连接服务器端,并可以发送消息给服务器端。下面是该程序的详细代码实现。
服务器端代码实现
```
import socket
import threading
# 定义服务器端口和IP地址
HOST = '127.0.0.1'
PORT = 9090
# 创建套接字对象
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定套接字并开始监听
server.bind((HOST, PORT))
server.listen()
# 定义连接列表
connections = []
def broadcast(msg, con):
"""
广播函数,将消息发送给连接到服务器的所有客户端
"""
for connection in connections:
if connection != con:
connection.send(msg)
def handle_client(con, addr):
"""
处理客户端连接函数
"""
while True:
try:
# 接收客户端消息
msg = con.recv(1024)
# 广播消息
broadcast(msg, con)
except:
# 如果发生异常则关闭连接并删除连接记录
con.close()
connections.remove(con)
break
while True:
# 等待客户端连接
con, addr = server.accept()
# 将新连接加入连接列表
connections.append(con)
# 输出客户端地址
print(addr, '已连接')
# 处理客户端连接
handle_thread = threading.Thread(target=handle_client, args=(con, addr))
handle_thread.start()
```
客户端代码实现
```
import socket
import threading
# 定义服务器端口和IP地址
HOST = '127.0.0.1'
PORT = 9090
# 创建套接字对象
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接服务器
client.connect((HOST, PORT))
def handle_input():
"""
处理键盘输入函数
"""
while True:
# 获取用户输入
msg = input()
# 发送消息给服务器端
client.send(msg.encode())
def handle_server():
"""
处理服务器端消息函数
"""
while True:
# 接收服务器端消息
msg = client.recv(1024).decode()
# 输出接收到的消息
print(msg)
# 启动两个线程分别处理用户输入和服务器端消息
input_thread = threading.Thread(target=handle_input)
input_thread.start()
server_thread = threading.Thread(target=handle_server)
server_thread.start()
```
测试方法
先运行服务器端代码,然后运行两个客户端代码,在两个客户端程序的终端分别输入消息,就可以实现聊天功能。
运行结果
首先是服务器端运行结果:
```
('127.0.0.1', 49823) 已连接
('127.0.0.1', 49824) 已连接
hello
nice to meet you
```
然后是两个客户端运行结果:
```
[输入] hello
[接收] hello
[输入] nice to meet you
[接收] nice to meet you
```
代码解析
下面对代码做一些简单的解析。
服务器端代码实现
首先我们定义了服务器端口和地址:
```
HOST = '127.0.0.1'
PORT = 9090
```
然后我们创建了套接字对象并绑定端口,开始监听客户端连接:
```
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen()
```
这里我们使用的是TCP协议,因此要创建SOCK_STREAM类型的套接字。bind()函数用于绑定IP地址和端口。listen()函数用于等待客户端连接。
接下来定义了一个广播函数和一个处理客户端连接的函数:
```
def broadcast(msg, con):
for connection in connections:
if connection != con:
connection.send(msg)
def handle_client(con, addr):
while True:
try:
msg = con.recv(1024)
broadcast(msg, con)
except:
con.close()
connections.remove(con)
break
```
广播函数用于将消息发送给所有连接到服务器的客户端。我们在处理客户端连接的函数中调用广播函数。
handle_client()函数中我们使用了一个死循环,以便接收客户端发送的消息。如果发生异常,则关闭连接并从连接列表中删除该连接。
接下来是服务器端的主程序:
```
while True:
con, addr = server.accept()
connections.append(con)
print(addr, '已连接')
handle_thread = threading.Thread(target=handle_client, args=(con, addr))
handle_thread.start()
```
在这里我们使用了一个死循环,以便等待客户端连接。当客户端连接到服务器时,我们将其连接对象和地址存储到连接列表中,并输出连接的客户端地址。然后我们调用handle_client()函数处理该客户端连接。
客户端代码实现
我们同样定义了服务器端口和地址:
```
HOST = '127.0.0.1'
PORT = 9090
```
然后我们创建套接字对象并连接到服务器端:
```
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((HOST, PORT))
```
接着定义了两个函数,一个用于处理用户输入,一个用于处理服务器端消息:
```
def handle_input():
while True:
msg = input()
client.send(msg.encode())
def handle_server():
while True:
msg = client.recv(1024).decode()
print(msg)
```
handle_input()函数用于处理用户输入的消息,并将其发送到服务器端。我们使用了encode()函数将字符串转化为字节流以便发送。handle_server()函数用于接收服务器端发送的消息,并将其输出到终端上。我们使用了decode()函数将字节流转化为字符串。
最后,我们创建了两个线程,分别处理用户输入和服务器端消息:
```
input_thread = threading.Thread(target=handle_input)
input_thread.start()
server_thread = threading.Thread(target=handle_server)
server_thread.start()
```
在这里我们使用了threading模块,分别创建了两个线程,一个用于处理用户输入,一个用于处理服务器端消息。我们使用了start()函数启动这两个线程。
总结
本文介绍了一个基于socket编程的实例:简单的聊天程序。我们使用了Python语言,通过socket模块实现了客户端和服务器端的交互。该程序可以实现两台计算机的通信,为理解socket编程提供了一个良好的实践例子。