栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

小型C/S开发框架——CSFrameWork(一)

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

小型C/S开发框架——CSFrameWork(一)

小型C/S开发框架——CSframeWork(一)

首先,要说明该框架是建立在一个多层次的系统下,共有三层——通信层,会话层和最外层(服务器和客户端)。其中,通信层是最低层,再上一层是会话层,最后是最外层(服务器和客户端)。我用一张图来大致表达一下它们之间的关系。

以下是该框架所有的类名称:
.

双工通信三要素

所谓双工,就是“双向通信工作”模式。
在C/S网络编程模式下,服务器与一个客户端进行双向通信时,必须拥有以下三要素:

Socket类的对象,即,通信端口封装类。由它才能创建下面的通信信道,并在结束通信时,关闭网络连接;DataInputStream类的对象。接收来自“对端”信息的输入通信信道;DataOutputStream类的对象。向“对端”发送消息的输出通信信道。 最底层——通信层的实现

通信层有以下功能:

    建立通信信道;提供发送,接收信息和关闭连接的方法;检查并发现对端异常掉线,并通知上一层处理。

通信层作为最底层,它是客户端和服务器建立联系的枢纽,是共用的一套代码,是能同时给服务器会话层和客户端会话层提供方法。

我们先看Communication类的线程代码片段:

这个线程不停的运行,而且通过第40行(message = this.dis.readUTF())不间断的侦听对端发送的消息。通过Boolean类型的goon判断何时停止线程的运行,并且当对端异常掉线时异常捕获块会判断goon的值,若为true,则说明时对端异常掉线,此时会执行一个抽象类方法peerAbnormalDrop(),交给上一层(ServerConversation 和 ClientConversation)具体处理异常掉线的情况。

向对端发送信息的方法:

下面是Communication类的完整代码:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public  abstract class Communication implements Runnable{
	protected Socket socket;
	protected String ip;
	protected DataInputStream dis;
	protected DataOutputStream dos;
	protected volatile boolean goon;
	
	Communication(Socket socket) throws IOException {
		this.socket = socket;
		this.ip = this.socket.getInetAddress().getHostAddress();
		this.dis = new DataInputStream(this.socket.getInputStream());
		this.dos = new DataOutputStream(this.socket.getOutputStream());
		
		this.goon = true;
		new Thread(this).start();
	}
	
	void send(NetMessage message) {
		try {
			this.dos.writeUTF(NetMessage.gson.toJson(message));
		} catch (IOException e) {
			//向对端发消息失败,意味着对端已关闭通信!
			//关闭网络连接
			close();
		}
	}
	
	public abstract void dealNetMessage(NetMessage netMessage);
	public abstract void peerAbnormalDrop();

	@Override
	public void run() {
		String message = "";
		while (this.goon) {
			try {
				message = this.dis.readUTF();
				NetMessage netMessage = 
						NetMessage.gson.fromJson(message, NetMessage.class);
				dealNetMessage(netMessage);
			} catch (IOException e) {
				if (this.goon == true) {
					//goon为true,意味着对端异常掉线!
					//调用异常掉线处理。
					this.goon = false;
					peerAbnormalDrop();
				} 
				//若goon为false,意味着正常正常下线,
				//则什么都不用做。
			}
		}
		close();
	}
	
	protected void close() {
		this.goon = false;
		try {
			if (this.dis != null) {
				this.dis.close();
			}	
		} catch (IOException e) {
		} finally {
			this.dis = null;
		}
		
		try {
			if (this.dos != null) {
				this.dos.close();
			}	
		} catch (IOException e) {
		} finally {
			this.dos = null;
		}
		try {
			if (this.socket != null && !this.socket.isClosed()) {
				this.socket.close();
			}	
		} catch (IOException e) {
		} finally {
			this.socket = null;
		}
	}
	
}
网络信息的规范化

客户端与客户端不仅要进行文字,图片,音频等信息的互相发送,客户端与服务器端还要进行“命令式”操作,比如,客户端下线,就要给服务器发送一个消息,告诉它该客户端要下线,进而做出一系列有关下线的操作。但这条消息应该与其他的聊天消息区别开来,即,把“会话内容”和“网络命令”严格区分开来!

为了表示“网络命令”的方便,我们使用Enum(枚举):

public enum ENetCommand {
	OUT_OF_ROOM,
	ID,
	OFFLINE,
	
	TO_ONE,
	TO_OTHER,
	TO_SP_OTHER,
	
	FORCEDOWN,
	

上面的各种命令都是自定义的,代表了不同的命令,例如,TO_ONE(私聊),OFFLINE(下线)等。

现在讲讲NetMessage类,该类的对象生成服务器端和客户端要发送的信息。在发送和接收时,网络上传输的是本类对象形成的字符串,在发送前和接收后,应该转换为本类对象。(由于本类是工具的内部核心类,严禁包外接触,所以修饰符是“包修饰符”,即,无修饰。

下面是NetMessage类的完整代码:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class NetMessage {
	public static final Gson gson = new GsonBuilder().create();
	private ENetCommand command;
	private String action;
	private String message;
	
	public NetMessage() {
	}

	String getAction() {
		return action;
	}

	NetMessage setAction(String action) {
		this.action = action;
		return this;
	}

	ENetCommand getCommand() {
		return command;
	}

	NetMessage setCommand(ENetCommand command) {
		this.command = command;
		return this;
	}

	String getMessage() {
		return message;
	}

	NetMessage setMessage(String message) {
		this.message = message;
		return this;
	}
	
	
}

我们会看到该类定义了三个成员,command(ENetcommand类型,代表命令),action(String类型,这里不解释,以后会有用处),message(String类型,代表文字消息)。

注意NetMessage类中的这句代码public static final Gson gson = new GsonBuilder().create(),有一个Gson的类,该类的作用是实现对象和json字符串之间的转换,需要用到gson.jar。


上图代码就解释了Gson的作用:

将网络命令语句TO_ONE和文字消息“我爱你姑娘呦!”转换成一个键值对形式的字符串,相当于对发送的信息进行包装,分类的整合起来,以便传输。然而,说到传输,我们便要开始提到会话层了!

会话层是由通信层Communucation类派生出来的,我们分为服务器会话层ServerConversation类和客户端会话层ClientConversation类。会话层的作用是处理客户端与服务器端之间的各种联系,是其联系的桥梁。由于最外层的客户端和服务器端还没有写,我们先构建出会话层的空壳,在将来服务器端和客户端写好后,就可以完成会话层的一系列功能。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/728490.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号