【MinaFile】【九】【2.0】客户端和服务器的handle的实现

服务器和客户端共同继承适配器类IoHandlerAdapter

 * 当客户端发来消息之后,会先调用自定义的解码器(类)。
 * 当解码器解码完成之后,再来这里进行业务处理。
 * 处理完之后(也就是调用write()方法之后),会再调用自定义的编码器(类)
 * 编码器(类)处理完之后,就发给客户端了。

1. 服务器端的实现 FileObjectServerHandler

/**
 * 当客户端发来消息之后,会先调用自定义的解码器(类)。
 * 当解码器解码完成之后,再来这里进行业务处理。
 * 处理完之后(也就是调用write()方法之后),会再调用自定义的编码器(类)
 * 编码器(类)处理完之后,就发给客户端了。
 * @author king_fu
 *
 */
public class FileObjectServerHandler extends IoHandlerAdapter {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(FileObjectServerHandler.class);

	@Override
	public void sessionCreated(IoSession session) throws Exception {
		LOGGER.info("客戶端又來了");
	}

	@Override
	public void sessionOpened(IoSession session) throws Exception {
		LOGGER.info("客戶端:" + session.getRemoteAddress().toString());
	}

	@Override
	public void sessionClosed(IoSession session) throws Exception {
		LOGGER.info("客戶端失去連接");
	}

	@Override
	public void sessionIdle(IoSession session, IdleStatus status)
			throws Exception {
		LOGGER.info("服務器空閒中");
	}

	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		LOGGER.info("服務器與客戶端交互發生異常");
		super.exceptionCaught(session, cause);
	}

	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		ByteFileMessage fm = (ByteFileMessage) message;
		PropertiesModel pm = ReadProperties.getModel();
		OutputStream os = null;

		try {
			// 用ObjectOutputStream的方式进行保存,打开之后会有乱码现象
			/*os = new ObjectOutputStream(new FileOutputStream(
					pm.getServerFilePath() + System.currentTimeMillis()
							+ fm.getFileName()));
			os.write(fm.getFileStream());
			os.flush();*/
			// 用PrintStream 
			os = new PrintStream(new FileOutputStream(
					pm.getServerFilePath() + System.currentTimeMillis()
							+ fm.getFileName()));
			os.write(fm.getFileStream());
			os.flush();
		} finally {
			os.close();
		}
		ByteReturnFileMessage brf = new ByteReturnFileMessage();
		brf.setSeq(fm.getSeq());
		brf.setReturnMassage("服务器保存文件完成。");
		brf.setReturnMassageLength(brf.getReturnMassage().getBytes().length);
		session.write(brf);

	}

	@Override
	public void messageSent(IoSession session, Object message) throws Exception {
		LOGGER.info("服務器信息已送達");
	}
}



2. 客户端的实现 FileObjectClientHandler

 * 客户端如果添加了自定义编码解码类
 * 那么,在发送给服务器的时候,信息会先经过编码器(类)
 * 然后再发送给服务器;
 * 
 * 如果实现了解码器,那么在服务器发送信息过来之后,
 * 就会先调用解码器。然后再进行业务处理


/**
 * 客户端如果添加了自定义编码解码类
 * 那么,在发送给服务器的时候,信息会先经过编码器(类)
 * 然后再发送给服务器;
 * 
 * 如果实现了解码器,那么在服务器发送信息过来之后,
 * 就会先调用解码器。然后再进行业务处理
 * @author king_fu
 *
 */
public class FileObjectClientHandler extends IoHandlerAdapter {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(FileObjectClientHandler.class);

	@Override
	public void sessionOpened(IoSession session) throws Exception {

		ByteFileMessage bfm = new ByteFileMessage();
		PropertiesModel pm = ReadProperties.getModel();
		if (!(new File(pm.getClientFilePath()).isDirectory())) {
			// 如果不是目录
			LOGGER.debug("当前目录:" + pm.getClientFilePath());
			throw new MyRuntimeException("在配置文件中未指定正确的目录路径:clientFilePath");
		}

		if (!(new File(pm.getClientFilePath() + pm.getClientFileName())
				.isFile())) {
			// 如果不是文件
			LOGGER.debug("当前文件:" + pm.getClientFilePath()
					+ pm.getClientFileName());
			throw new MyRuntimeException("在配置文件中未指定正确的文件路径:clientFileName");
		}

		bfm.setSeq(1);
		// 封装文件路径;路径名+文件名
		bfm.setFilePath(pm.getClientFilePath() + pm.getClientFileName());
		session.write(bfm);
	}

	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		LOGGER.info("客户端與服务器交互發生異常");
		super.exceptionCaught(session, cause);
	}

	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		ByteReturnFileMessage returnMessage = (ByteReturnFileMessage) message;
		LOGGER.info("返回的序号:" + returnMessage.getSeq());
		LOGGER.info("服务器返回的消息:" + returnMessage.getReturnMassage());
		session.close(true);
	}

	@Override
	public void messageSent(IoSession session, Object message) throws Exception {
		LOGGER.info("客户端信息已送達");
	}
}

到了这里,客户端和服务器的IoHandle实现了。

最新代码已经更新在github中,欢迎fork。

项目名:MinaFile












 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是Python实现TCP客户端服务器(多线程)的代码示例: TCP服务器端代码: ```python import socket import threading # 定义监听的IP和端口号 bind_ip = "0.0.0.0" bind_port = 9999 # 创建TCP服务器套接字 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((bind_ip, bind_port)) server.listen(5) print("[*] Listening on {}:{}".format(bind_ip, bind_port)) # 处理客户端请求的线程函数 def handle_client(client_socket): # 打印客户端发送的数据 request = client_socket.recv(1024) print("[*] Received: {}".format(request)) # 发送响应数据 client_socket.send(b"ACK!") client_socket.close() while True: # 等待客户端连接 client, addr = server.accept() print("[*] Accepted connection from {}:{}".format(addr[0], addr[1])) # 创建新线程处理客户端请求 client_handler = threading.Thread(target=handle_client, args=(client,)) client_handler.start() ``` TCP客户端代码: ```python import socket # 定义连接的服务器IP和端口号 target_ip = "127.0.0.1" target_port = 9999 # 创建TCP客户端套接字 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect((target_ip, target_port)) # 发送数据给服务器 client.send(b"Hello, server!") # 接收服务器的响应数据 response = client.recv(1024) print("[*] Received: {}".format(response)) client.close() ``` 这里的TCP服务器端使用了多线程来处理客户端请求,每个新连接都会创建一个新的线程来处理。TCP客户端服务器发送数据后,会等待服务器的响应。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值