`
feng1990liu
  • 浏览: 8611 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
文章分类
社区版块
存档分类
最新评论

通信小结

 
阅读更多

     最近好多天都在写通信的程序,刚开始讲时,服务器和客户端都没用到自己设计的界面,觉得很简单,服务器端有一个ServerSocket,客户端有一个Socket,简简单单的建立一个通道,后来给服务器和客户端加界面时,才发现自己并没有真正的掌握这些知识,胡哥刚讲完同步画板时,吕旭当天上午就实现了,而我觉得好高深啊,怎么实现的???虽然有些交流可总觉得自己还没入门。那两天真是不知道天天在写什么,有时听得懂被人讲的,看得懂别人的代码,就是自己不会写。。。(用某人的话说这些没有意义)

    周二早上怀着惴惴不安的心情来到公司,因为没写完作业,周一休息,不会写也不怎么想写,(不会俩字很敏感)书上代码敲了一遍,敲完基本什么也没记住。。。周二上午没讲课,大神李伟给我仔仔细细分析了框架,说了大略思路,唉,觉得自己明白了,开悟了。。。

   为了给设计程序一个良好的框架,胡哥给我们讲了UML作图,这个的话,如老师所说,框架很详细的话,只往框架中填代码就好了,“初中生培训三个月就可以完成”。。。可是我觉得大道至简,其实书设计思路不够熟练于是框架就变成了这样

  服务器框架

 客户端框架



  服务器客户端界面通信

大概讲,服务器要有3个方法

ServerSocket so=new ServerSocket(port);

 

//读取数据
	private String readString(InputStream ins) throws IOException{
		//创建一个字符串缓冲区
		StringBuffer stb=new StringBuffer();
		char c=0;
		while(c!=35){
			//遇到#号算一个字符串
			int i=ins.read();//读取客户机发过来的一个字节
			c=(char)i;//将输入的字节转换为一个char
			stb.append(c);
		}
		//将读到的字节转化为字符串,并调用trim去掉尾部的空格
		String inputS=stb.toString().trim();
		return inputS;
	}
	区分客户端发给服务器,还是群发,加了个标志值(c)
	int c=ins.read();
		if(c==1){//只发给服务器
			String inputS=readString(ins);
			while(!inputS.equals("bye")){
				System.out.println("客户机说"+inputS);
				//加到空白区域
				are.setText(are.getText()+"\r\n"+inputS);
				inputS=readString(ins);//读取客户机下一次输入
			}
		}else if(c==2){//发送给系统
			String inputS=readString(ins);
			while(!inputS.equals("bye")){
				System.out.println("客户机说"+inputS);
				//加到空白区域
				are.setText(are.getText()+"\r\n"+inputS);
				//群发给其他客户端
				StartListener.sendMsg(inputS);
				inputS=readString(ins);//读取客户机下一次输入
			}
		}

 

//发送消息给连接我的客户端
	public  void sendMsg2Me(String msg){
		try{
		msg+="#";
		out.write(msg.getBytes());
		}catch(Exception ef){
			ef.printStackTrace();
		}
	}

 这3个方法可能分布在不同的类中,类与类之间也因此相互连接

客户端与服务器端相对应,方法也相对应

       

Socket client=new Socket("IP",port);

 

public void  Connect(){
		
		try{
			ous=so.getOutputStream();//获取输出流
			System.out.println("服务器连接成功!");
			while(true){
				//读取服务器发来的消息
				ins=so.getInputStream();//获取输入流
				String message="";
				int b = ins.read();
				while(b!=35){
					//#号结尾
					message +=(char)b;
					b = ins.read();
				}
				//显示在客户端的area上
				are.setText(are.getText()+"\r\n"+message);
				System.out.println("服务器传过来的是="+message);
			}
		
		}catch(Exception e){
			e.printStackTrace();
		}
	}

 

//发送消息
	public  void sendMsg(String s){
		byte [] by=s.getBytes();
		try {
			ous.write(by);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

 最后效果

1.客户端发给服务器

 2.客户端群发



 3.一行代码解决汉字乱码

//读取汉字

message=new String(message.getBytes("ISO-8859-1"),"GB2312");



 

其实关于服务器与客户端的读写,在做同步画板时更能深刻体现,一边写进去什么dou.writeInt(),另一边就即读取什么dis.readInt();

					x2=e.getX();
					y2=e.getY();
					 if(s.equals("画线")){
						g.drawLine(x1, y1, x2, y2);
						try{
						dos.writeInt(1);
						dos.writeInt(x1);
						dos.writeInt(y1);
						dos.writeInt(x2);
						dos.writeInt(y2);
						System.out.println("x1="+x1+" y1="+y1+" x2="+x2+" y2="+y2);
						}catch(Exception e1){
							e1.printStackTrace();
						}
					}else if(s.equals("画圆")){
						int r1=Math.abs(x2-x1);
						int r2=Math.abs(y2-y1);
						g.drawOval(x1, y1, r1, r2);
						try{
						dos.writeInt(2);
						dos.writeInt(x1);
						dos.writeInt(y1);
						dos.writeInt(r1);
						dos.writeInt(r2);
						System.out.println("x1="+x1+" y1="+y1+" x2="+x2+" y2="+y2);
						}catch(Exception e1){
							e1.printStackTrace();
						}
					}else if(s.equals("画图")){
						ImageIcon con=new ImageIcon("images/psb.jpg");
						//缓冲图纸,实为窗体性质
						image01=new BufferedImage(con.getIconWidth(),con.getIconHeight(),BufferedImage.TYPE_INT_RGB);
						Graphics g2=image01.getGraphics();
						g2.drawImage(con.getImage(), 0, 0, null);
						//白纸划到窗体上
						g.drawImage(image01, 0, 0, null);
						try{
							int width=image01.getWidth();
							int height=image01.getHeight();
							dos.writeInt(3);
							dos.writeInt(width);
							dos.writeInt(height);
							//把每个像素点的颜色写进去
							for(int i=0;i<width;i++){
								for(int j=0;j<height;j++){
									dos.writeInt(image01.getRGB(i, j));
								}
							}
						}catch(Exception e1){
							e1.printStackTrace();
						}
					}

 

//读出数据的方法
	public void readMsg(InputStream ins){
		try {
			while(true){
				DataInputStream dis=new DataInputStream(ins);
				int type=dis.readInt();
				if(1==type){
				//读取客户端画线的数据
				int x1=dis.readInt();
				int y1=dis.readInt();
				int x2=dis.readInt();
				int y2=dis.readInt();
				System.out.println("x1="+x1+" y1="+y1+" x2="+x2+" y2="+y2);
				g.drawLine(x1,y1,x2,y2);
				}else if(2==type){
					//读取客户端画圆的数据
					int x1=dis.readInt();
					int y1=dis.readInt();
					int r1=dis.readInt();
					int r2=dis.readInt();
					g.drawOval(x1, y1, r1, r2);
				}else if(3==type){
					//读取客户端画图的数据
					int width=dis.readInt();
					int height=dis.readInt();
					for(int i=0;i<width;i++){
						for(int j=0;j<height;j++){
							g.setColor(new Color(dis.readInt()));
							g.drawLine(i, j, i, j);
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

 

最终同步画板的效果



 

 

 在写客户端时用了鼠标监听器和事件监听器都为内部类,内部类最大的好处是基本上省略了传参过程,节省很多代码,最大的缺点是不清晰,在编程语言类往往讲究清晰第一,在写服务器端是鼠标监听器和时间监听器均是外部类,尝试了一下,过程中出现过空指针,但都不是什么大问题,容易解决。在写的过程中还犯了个错误,用了static的一个getter方法,导致同步时服务器只能同步客户端的一条线,原因是第二个调用getter方法覆盖了前一次的数据,static用时需谨慎和思路很清晰啊。。。。。

 

  • 大小: 13.8 KB
  • 大小: 30.6 KB
  • 大小: 4.7 KB
  • 大小: 5.6 KB
  • 大小: 84.2 KB
  • 大小: 19.1 KB
  • 大小: 129.4 KB
  • 大小: 33.6 KB
分享到:
评论

相关推荐

    Java Socket通信小结

    Java Socket通信小结 在Java编程中,Socket通信是一种基于TCP/IP协议的网络通信方式,它允许两个应用程序之间建立可靠的、双向的数据传输连接。本文将深入探讨Java Socket通信的基础知识,以及如何通过Java实现一个...

    关于CP1H变频器通信小结.pdf

    【CP1H变频器通信小结】 本文主要围绕CP1H变频器与Modbus-RTU通信的配置和特点进行阐述。CP1H变频器是三菱电机推出的一款可编程控制器,它具备串口通信功能,可以与其他设备通过Modbus-RTU协议进行数据交换。 **...

    linux下Qt通信小结.pdf

    在Linux环境下进行Qt应用程序开发时,串口通信是一项常见的需求。Qt本身虽然没有提供专门的串口通信类,但可以通过QIODevice抽象层与其他系统接口进行交互。本文将总结作者在Linux下使用Qt进行串口通信的经验,探讨...

    进程通讯总结及测试

    进程间的通信(IPC,Inter-Process Communication)是操作系统中一种重要的功能,允许不同进程之间交换信息,协同工作。本文将重点讨论其中的共享内存方式。 共享内存是一种高效的数据交换机制,它允许多个进程共享...

    通信实训小结.pdf

    "通信实训小结" 通信实训小结是指在通信领域中的实习或实践活动,本文档记录了某个实习生的两周实习经历,包括了实习的内容、收获的知识、以及未来努力的方向。 一、通信实训内容 通信实训的内容涵盖了多个方面,...

    基于SIMATIC S7-300/400 服务器软件包的IEC61850通信规约快速入门

    #### 4 “IEC61850ServerLibrary“软件包通信小结 通过以上步骤,我们可以成功地将SIMATIC S7-300 PLC配置为IEC61850服务器,并通过“IEC61850ServerLibrary”软件包实现了与基于IEC61850标准的其他设备之间的通信...

    通信广场营业员精编工作小结.rar

    通信广场营业员精编工作小结.rar

    中级通信专业实务传输与接入教程章节小结

    《通信专业实务:传输与接入》是一本针对全国通信专业技术人员职业水平考试的教程,它涵盖了有线和无线传输与接入的重要技术。该书旨在帮助考生掌握通信领域的核心概念和实际应用。 首先,书中详细讲解了有线传输与...

    Delphi Socket 通信编程要点小结

    ### Delphi Socket 通信编程要点小结 #### 一、引言 在现代通信系统开发过程中,基于Delphi的Socket编程技术因其高效性与灵活性而备受青睐。本文将结合实践经验,对Delphi环境下进行Socket通信时所遇到的关键问题...

    通信广场营业员精编工作小结.pdf

    标题中的“通信广场营业员精编工作小结”暗示了这份文档主要涵盖了通信广场营业员的工作总结和经验分享,这通常涉及到与客户服务、销售技巧、业务处理效率以及个人职业素养等相关的内容。描述中提到的“展示企业形象...

    现代通信技术实验报告(程控,移动通信)

    现代通信技术报告,关于程控交换机和移动通信切换

    现代通信系统原理网络教材_

    本章知识点小结 第二章 信道与噪声 2.1 信道的基本概念 2.2 恒参信道及其对所传信 号的影响 2.3 随参信道及其对所传信 号的影响 2.4 信道的加性噪声 2.5 通信中的常见噪声 2.6 信道...

    2019年通信广场营业员个人小结.doc

    【通信广场营业员职责与挑战】 作为一名通信广场的营业员,我深知自己的职责不仅仅是销售通信产品和服务,更是代表企业形象,展现"移动人"的专业素养和热情态度。我们的工作是与客户面对面交流的"窗口",是连接企业...

    实验一 进程通信——管道和信号实验报告.doc

    本次实验是关于操作系统中的进程通信,主要涉及了进程的创建、控制、以及多种通信方式,包括信号通信和管道通信。通过实验,目的是加深对进程概念的理解,掌握并发执行的本质,并学习如何解决进程间的互斥问题。实验...

    移动通信原理.pdf

    介绍移动通信原理,供广大通信专业人员学习

    移动通信重点总结.doc

    第二代移动通信系统 --- 2G:数字系统 基本特征:数字技术、数字处理电路SIM卡,手机体积小质量轻、 大容量,TDMA/FDD, CDMA/FDD; 主流标准:GSM,NADC(IS-136),PDC(TDMA); IS-95(CDMA) ; 第三代移动通信系统 -...

Global site tag (gtag.js) - Google Analytics