基于tcp的服务端客户端通信python_基于TCP的Socket编程实现客户端与服务器端的通信,socket,client,和,server...

本文介绍了如何使用Python的TCP Socket编程实现多线程服务器(支持群聊)与单线程客户端之间的通信。通过创建TcpChatServer类和TcpCilent类,实现了服务器监听、连接管理、数据收发以及客户端的双向数据传输功能。实验环境为Python 3.8.2、Windows10和PyCharm。
摘要由CSDN通过智能技术生成

基于TCP的socket编程实现client和server通信

.

实验内容:

.

client为单线程、server为多线程(群聊功能)

.

原理:

.

套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。

.

环境:

.

Python 3.8.2、Windows10、pycharm

.

实验过程:

.

一、先编写服务器实现群聊、

.

cb41baf3ad16ef0c5b551b4b612a7068.png

成功建立连接、每个线程都有自己文件占位符fd和端口号port:

77b32c156993d4c69a96df324b4d5dc0.png

三个client共同发送消息、验证群聊

67cb931b32df05ca55a656cb9517e306.png

群聊实现,每个client都收到来自时间、端口各异的消息

80330b18a11e4ac82d2b956e773d56a0.png

a74c7738187ad73e69f52bb0581812ef.png

TcpServer代码

#服务端

import socket

import threading #基于线程的并行

import logging #Python 的日志记录工具

import datetime #基本的日期和时间类型

FORMAT = "%(asctime)s %(threadName)s %(thread)d %(message)s"

logging.basicConfig(format=FORMAT, level=logging.INFO)

#创建类

class TcpChatServer:

#初始化、ip、port

def __int__(self, ip='127.0.0.1', port=9999):

self.addr = (ip, port)

self.sock = socket.socket()

self.clients = {} #空字典储存已有进程

#开启

def start(self):

self.sock.bind(self.addr)

self.sock.listen() #服务启动、开始监听

threading.Thread(target=self.accept, name='accept').start() #开始线程活动

def accept(self):

while True:

s, raddr = self.sock.accept() #返回新的套接字对象和客户端IP地址

logging.info(s)

logging.info(raddr)

#key = raddr, values = s

self.clients[raddr] = s

threading.Thread(target=self.recv, name='recv', args=(s,)).start()

def recv(self, sock:socket.socket):

while True:

try: #异常处理

data = sock.recv(1024) #阻塞点

logging.info(data) # 打印拿到的数据

except Exception as e:

logging.error(e)

data = b'quit'

if data == b'quit':

self.clients.pop(sock.getpeername())

break

msg = "ack{}. {} {}".format( #数据整理=地址+时间+内容

sock.getpeername(),

datetime.datetime.now().strftime("%Y/%m/%d-%H:%M:%S"),

data.decode()).encode()

#一对多、发送所有接受的数据

for s in self.clients.values():

s.send(msg)

#发送

def send(self, cmd):

sMsg = "send{}. {} {}".format(

self.sock.getsockname(), #Return the socket's own address

datetime.datetime.now().strftime("%Y/%m/%d-%H:%M:%S"),

cmd).encode()

# self.sock.send(sMsg)

# 一对多、发送所有接受的数据

for s in self.clients.values():

s.send(sMsg)

#停止

def stop(self):

for s in self.clients.values():

s.close()

self.sock.close()

#custom

cs = TcpChatServer()

cs.__int__()

cs.start()

#测试、输入显示当前进程

while True:

cmd = input("输入show查看当前进程,输入quit关闭服务器\n")

if cmd.strip() == 'quit': #移除字符串头尾指定的字符(默认为空格或换行符)或字符序列

cs.stop()

threading.Event.wait(3) #阻塞线程直到内部变量为true

break

elif cmd.strip() == 'show':

logging.info(threading.enumerate()) # 以列表形式返回当前所有存活的 Thread 对象

else:

cs.send(cmd)

.

二、再编写客户端、

.

连接服务器

8e238696e954da45ac43b158d0775234.png

实现双向数据传输

002caa56060fff0e9bf8b259795ddbb9.png

TcpClient代码

#客户端

import socket

import datetime

import threading

class TcpCilent:

def __int__(self):

host = '127.0.0.1'

port = 9999

raddr = (host, port)

self.bufsize = 1024 # 指定接收数据大小

self.tcpCilent = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建TCP Socket

self.tcpCilent.connect(raddr) # 连接

threading.Thread(target=self.send, name='send').start() # 开始线程活动

threading.Thread(target=self.recv, name='recv').start()

def send(self):

#发送数据

while True:

cmd = input("输入要发送的数据、输入quit断开连接:\n")

if cmd.strip(':') == 'quit':

self.stop()

break

cMsg = "send{}. {} {}".format(

self.tcpCilent.getsockname(),

datetime.datetime.now().strftime("%Y/%m/%d-%H:%M:%S"),

cmd

)

self.tcpCilent.send(cMsg.encode())

def recv(self):

while True:

#接收数据

try:

data = self.tcpCilent.recv(self.bufsize)

except Exception as e: #常规错误的基类、线程释放问题?

print(e)

data = ""

if not len(data):

break

sMsg = "ack{}. {} {}".format( # 数据整理=地址+时间+内容

self.tcpCilent.getpeername(),

datetime.datetime.now().strftime("%Y/%m/%d-%H:%M:%S"),

data.decode())

print(sMsg)

def stop(self):

self.tcpCilent.close()

cs = TcpCilent()

cs.__int__()

.

三、最后实现两者通信

.

cmd运行server、pycharm运行client、建立socket连接

5fd62a995451e91649ddf3084ea596f3.png

fd5ca045d576b6f24bd62ca794424a47.png

验证互相通信

65c4c927b98ead6766d540fa1e1e518b.png

b4c268bed63c2c1fd8fdae4f91fea590.png

.

.

.

Windows 下的 socket 程序和 Linux 思路相同,但细节有所差别:

Windows 下的 socket 程序依赖 Winsock.dll 或 ws2_32.dll,必须提前加载。DLL 有两种加载方式,请查看:动态链接库DLL的加载

Linux 使用“文件描述符”的概念,而 Windows 使用“文件句柄”的概念;Linux 不区分 socket 文件和普通文件,而 Windows 区分;Linux 下 socket() 函数的返回值为 int 类型,而 Windows 下为 SOCKET 类型,也就是句柄。

Linux 下使用 read() / write() 函数读写,而 Windows 下使用 recv() / send() 函数发送和接收。

关闭 socket 时,Linux 使用 close() 函数,而 Windows 使用 closesocket() 函数,python中socket模块也是用的socket.close()。

dows 区分;Linux 下 socket() 函数的返回值为 int 类型,而 Windows 下为 SOCKET 类型,也就是句柄。

Linux 下使用 read() / write() 函数读写,而 Windows 下使用 recv() / send() 函数发送和接收。

关闭 socket 时,Linux 使用 close() 函数,而 Windows 使用 closesocket() 函数,python中socket模块也是用的socket.close()。

好的,我会一步步回答您的问题。 1. 实现基于 TCP 协议服务端客户端通信: (1)服务端代码: ```python import socket HOST = '127.0.0.1' # 本地地址 PORT = 8888 # 端口号 # 创建一个TCP/IP套接字 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定地址和端口号 server_socket.bind((HOST, PORT)) # 开始监听连接 server_socket.listen(1) # 等待连接 print('等待客户端连接...') conn, addr = server_socket.accept() print('客户端连接成功,客户端地址:', addr) while True: # 接收数据 data = conn.recv(1024) if not data: break print('接收到客户端数据:', data.decode('utf-8')) # 发送数据 conn.sendall('已收到你的消息!'.encode('utf-8')) # 关闭连接 conn.close() ``` (2)客户端代码: ```python import socket HOST = '127.0.0.1' # 服务端地址 PORT = 8888 # 端口号 # 创建一个TCP/IP套接字 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接服务端 client_socket.connect((HOST, PORT)) # 发送数据 client_socket.sendall('你好,服务端!'.encode('utf-8')) # 接收数据 data = client_socket.recv(1024) print('接收到服务端数据:', data.decode('utf-8')) # 关闭连接 client_socket.close() ``` 2. 实现基于 UDP 协议服务端客户端通信: (1)服务端代码: ```python import socket HOST = '127.0.0.1' # 本地地址 PORT = 8888 # 端口号 # 创建一个UDP套接字 server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 绑定地址和端口号 server_socket.bind((HOST, PORT)) print('等待客户端连接...') while True: # 接收数据 data, addr = server_socket.recvfrom(1024) print('接收到客户端数据:', data.decode('utf-8')) # 发送数据 server_socket.sendto('已收到你的消息!'.encode('utf-8'), addr) ``` (2)客户端代码: ```python import socket HOST = '127.0.0.1' # 服务端地址 PORT = 8888 # 端口号 # 创建一个UDP套接字 client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 发送数据 client_socket.sendto('你好,服务端!'.encode('utf-8'), (HOST, PORT)) # 接收数据 data, addr = client_socket.recvfrom(1024) print('接收到服务端数据:', data.decode('utf-8')) # 关闭连接 client_socket.close() ``` 以上就是基于 TCP 和 UDP 协议实现服务端客户端通信的代码,希望能够帮到您。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值