`
Kslsi
  • 浏览: 22574 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

通信之入门

    博客分类:
  • java
阅读更多



         最近开始通信部分的学习,也有很久没有写技术博客了,java也荒废了整整一学期了,可能本学期也会比较忙,但是这边的项目什么的还是得慢慢跟着走,虽然慢,但总是还在进步,这就已经很好了(不是在下追求不高,实在是考虑个人情况尽全力而行),这学期的任务主要就是把上学期的线程小游戏抓紧做好并完善,然后还有和小伙伴儿们一起做一个仿微信——享聊。

  

       对于通信部分,目前个人认为只是入了门,从开始的服务器,到现在的客户端,也是一种进步吧。下面就说说写服务器的步骤。

 

       1.根据端口port实例化ServerSocket类对象,即服务器类对象,实现代码:

ServerSocket server = new ServerSocket(port);//port为端口号

 

       2.让服务器进入等待,等待客户机的接入,当客户机接入之后,生成一个客户机Socket对象,实现代码:

Socket client = server.accept();

 

        3.从客户机连接对象上获取输入流与输出流对象,实现代码:

OutputStream os = client.getOutputStream();
InputStream is = client.getInputStream();

 

      4.消息发送,这一步是从开始的输出一个字节(int型)慢慢改进到输出一整句话,这个地方就涉及到协议,在客户机输入的内容中,哪些才是一句话,确定那几个字节组成的是一句话后,就将其整体输出。

       (1)字节输出方法代码:

	// 获取字符串的字节数组
	byte[] data = s.getBytes();
	// 用输出流对象发送
	os.write(data);
	// 强制输出
	os.flush();
	int in = 0;//一个字节一个字节的读取客户机的输入
	while(in !=13){//如果读到的不是13,即回车字符
		in = is.read();
		System.out.println("读到的一个是:"+in);
	}
	System.out.println("客户按了回车键,退出:"+in);

 

       (2)整句输出就是多了一个readString方法使用了字符串缓冲对象,代码如下:

	private String readString(InputStream is){
		//创建一个字符串缓冲区对象
		StringBuffer buf = new StringBuffer();
		try{
			char c = 0;
			while(c != 13){//遇到一个换行,就表示之前的数据是一句话
				int i = is.read();//读取客户机发来的一个字节
				c = (char) i;//将输入的字节强制转换成一个char
				buf.append(c);//将char追加到字符串缓冲对象中
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		//将读取到的字节转换为字符串,并去掉首尾空格
		return buf.toString().trim();
	}

 

       利用以上的代码就可以写出一个简单的服务器了,当然,在程序中添加一些输出语句是可以很大程度上提高程序调试的效率的,大家可以多用用,不过值得注意的是在已经成熟的软件中最好把为了测试而写的输出语句删掉,否则会占用更多内存,减缓程序运行速度。另外,相信大家已经发现了,按照这个过程写出来的服务器是只能接一个客户端的,原因是这是一个单线程的程序,由此,为了能接多个客户端,我们可以将其写进线程中。

 

       由上面的方法写出来的服务器只能实现服务器与客户端之间的数据接收,那么如何实现一个客户端与另一个客户端之间,甚至多个客户端之间的数据接收呢?这个就让我们想到我们可以用一个队列对象将线程保存,而且这个队列对象必须是一个全局变量,于是就另外写一个提供方法调用的类,转发消息。代码如下:

import java.util.ArrayList;
import java.util.List;

public class ChatTools {
	//创建一个保存处理线程的队列对象
	private static List<ServerThread> staList= new ArrayList();
	
	//私有属性的构造方法,因为不在外部创建此对象
	private ChatTools(){}
	
	/**
	 * 将客户端对应线程对象加入到队列中
	 * @param client 要加入的客户机线程对象
	 */
	public static void addClient(ServerThread st){
		int i = staList.size()+1;
		castMsg("小伙伴们,我来了!目前在线人数为:"+i);
		staList.add(st);
	}
	//将一条消息发送给队列中的其他客户机处理对象
	public static void castMsg(String msg) {
		msg = "有人说话:" + msg;
		for(int i=0; i<staList.size(); i++){
			ServerThread st = staList.get(i);
			st.sendMsgToMe(msg);
		}
	}
}

 

         通过调用此类里面的方法,我们就可以实现群聊的基本功能了。

 

          接下来就是客户端的实现,客户端的实现很简单,只需要一句代码就OK:

Socket client=new Socket(“服务器IP”,服务器端口);

 

       然后其他的消息读取的方法都是和服务器是相同的,这个我就不多说了,然后在写客户端的时候,客户端是应该有一个界面的,于是乎,我就做成了介个样子~~介个上面的消息大家也是可以忽略的~~


          然后,我又很无聊滴开了好几个客户端,不过每个界面都是不一样的~~

 

       目前就做到这个程度,还有很多问题没有解决,比如中文乱码,还有注册账号等问题,这些问题都会慢慢解决的。

 

 

       最后总结一下,通信这一块,除了创建服务器和客户端的方法以及关于协议方面的东西以前没有接触过,其他的都是以前线程小游戏中用过的,所有衔接还是比较重要的,不过之前的学得不扎实的话,也可以通过这一块的学习巩固,可能会慢一点,不过还是那句话,速度慢总比不进步好!

       OK,本年度第一篇总结完毕,鼓励一下自己(少臭美啦),只能说,继续努力!

 

  • 大小: 41.5 KB
  • 大小: 139 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics