通信,指人与人或人与自然之间通过某种行为或媒介进行的信息交流与传递,从广义上指需要信息的双方或多方在不违背各自意愿的情况下无论采用何种方法,使用何种媒质,将信息从某方准确安全传送到另方。[百科释义]
个人认为通信就是通过特定规格(所谓的协议)传输和读取信息。就像男女之间的交往,可以通过不同途径认识的一样,这种协议并不是每家公司或者每个人都是一样的,如果一样,接触过协议的人就可以轻松破解传输的信息并读取,于是就有了通信安全。所以通信的主要内容就是文件的传输和读写,而文件的传输的读写只要就依靠协议的制定,就通信部分而言,刚接触到协议,对通信有了简单的认识
简单叙述下创建服务器和客户端的过程
服务器创建:
第一步:在指定端口上创建一个java.net.ServerSocket对象,如下代码:
ServerSocket server=new ServerSocket(8023); System.out.println("服务器创建成功!"+port);
第二步:当服务器创建成功后,让服务器进入等待状态,等待其它的客户机来连结:
//在等待客户机连结进入,进入后,生成一个Socket对象 java.net.Socket client=server.accept(); System.out.println("Incoming "+client.getRemoteSocketAddress());
第三步:从Socket连结对象上调用方法得到输入输出流:
java.net.Socket client=server.accept(); //从连结对象上得到输入/输出流对象 OutputStream out=client.getOutputStream(); InputStream ins=client.getInputStream();
客户端创建
Socket client=new Socket(“服务器IP”,服务器端口);
在谈谈对编写这个网络画板过程吧,最初的想法是做成一个聊天登录界面,可以发送消息,然后输入框为空的时候点击“Send”按钮是就会弹出一个窗体,客户端此时也会弹出与服务器属性相同的窗体,然后就可以在窗体上绘图,然后客户端显示的图形与服务器画的一样。
expectation:
但是,理想很丰满,现实很骨感...于是在各个文件传参的时候出现的如下的情况...
于是就从各个文件中找各个参数,逐一地测试,输出,特别是从监听器中传参出来,简直就是一个恶魔在心头萦绕。有几个参数传到目的文件要经过几个文件,这也难怪会出现上述问题,这么多文件总有那么几个文件会出问题...
最后,采取了一个比较折中的方式,就是暂时取消了发送消息的功能和登录验证的功能,以后有必要再加上去,添加了菜单栏,并将绘图命令集成在菜单项中。
再感悟:经过这次简单网络画板的设计,我感到自己在模块整合方面还有待提高,自己写的代码与“搞内聚,低耦合”的理念有一定的距离,但我相信这将会是一个好的开始,并将激励我们发展优秀的设计思路,合理的软件布局。我也相信经过时间的洗礼,骨感的现实终将丰满起来、、、
简单网络画板代码
package com.netBord20130729; import java.awt.Color; import java.awt.Desktop; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.URI; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JSeparator; /** * 简单网络画板服务器端 * 界面+通信 * 继承自Thread线程类,实现MouseListener接口 * @author YangKang * */ public class NetDrawBordServer extends Thread implements MouseListener{ //定义属性,用来存储按下和释放的坐标值 private int x1; private int y1; private int x2; private int y2; private int port = 8023; //服务器端口号 private ServerSocket server; //服务器 private Graphics g; //画布对象 private OutputStream ous; //输出流对象 private InputStream ins; //输入流对象 private DataOutputStream dous; //数据输出流 private DataInputStream dins; //数据输入流 private Socket client; //客户端 private byte type; //绘制图形的类型 private String drawCmd = "null"; //菜单命令 //定义入口主函数 public static void main(String args[]) { NetDrawBordServer ndbs = new NetDrawBordServer(); ndbs.GUI(); ndbs.Conn2Client(); } /** * 创建一个窗体,作为服务器端的画板 */ private void GUI() { JFrame netBord = new JFrame(); netBord.setTitle("网络画板服务器端"); netBord.setSize(new Dimension(600,500)); netBord.setDefaultCloseOperation(0);//设置默认关闭操作为不执行任何操作 netBord.setLocationRelativeTo(null); netBord.setLayout(new FlowLayout(FlowLayout.LEFT));//设置窗体布局方式为流式布局 //添加窗体左上角及最小化的图标 ImageIcon frame_icon =new ImageIcon("netPic/0.jpg"); netBord.setIconImage(frame_icon.getImage()); //添加一个退出确认弹出框,前面定义关闭方式为0 netBord.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e) { if(JOptionPane.showConfirmDialog(null,"是否退出")==JOptionPane.OK_OPTION){ System.exit(0); } } }); //创建菜单条 JMenuBar menuBar = new JMenuBar(); //创建菜单 JMenu menuF = new JMenu("文件(F)"); //添加菜单项 JMenuItem newItem = new JMenuItem("新建(N)"); JMenuItem openItem = new JMenuItem("打开(O)"); JMenuItem saveItem = new JMenuItem("保存(S)"); //实例化一个水平分隔符对象 JSeparator jse = new JSeparator(); JMenuItem exitItem = new JMenuItem("退出(E)"); //将菜单添加到窗体中 netBord.add(menuBar); //菜单添加到菜单条 menuBar.add(menuF); //将菜单项添加到菜单 menuF.add(newItem); menuF.add(openItem); menuF.add(saveItem); menuF.add(jse); menuF.add(exitItem); JMenu menuE = new JMenu("编辑(E)"); JMenuItem drawLine = new JMenuItem("画直线(L)"); JMenuItem drawOval = new JMenuItem("画椭圆(O)"); JMenuItem drawRect = new JMenuItem("画矩形(R)"); JMenuItem drawTri = new JMenuItem("画三角形(T)"); menuBar.add(menuE); menuE.add(drawLine); menuE.add(drawOval); menuE.add(drawRect); menuE.add(drawTri); JMenu menuH = new JMenu("帮助(H)"); JMenuItem aboutItem = new JMenuItem("关于(A)"); menuBar.add(menuH); menuH.add(aboutItem); //给菜单项添加动作监听器,menuListener为内部监听器 openItem.addActionListener(menuListener); saveItem.addActionListener(menuListener); exitItem.addActionListener(menuListener); drawLine.addActionListener(menuListener); drawOval.addActionListener(menuListener); drawRect.addActionListener(menuListener); drawTri.addActionListener(menuListener); aboutItem.addActionListener(menuListener); //最后加上set语句可以将菜单栏添加到窗体顶部 netBord.setJMenuBar(menuBar); netBord.setVisible(true); //在窗体可见之后,获取画布的对象 g = netBord.getGraphics(); //给窗体添加鼠标监听器 netBord.addMouseListener(this); } /** * 菜单栏内部监听器,用于将采集所有菜单栏的命令 */ ActionListener menuListener = new ActionListener() { public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if("画直线(L)".equals(cmd)){ drawCmd = "line"; System.out.println("画直线的监听器启动:"+drawCmd); }else if("画椭圆(O)".equals(cmd)){ drawCmd = "oval"; System.out.println("画椭圆的监听器启动:"+drawCmd); }else if("画矩形(R)".equals(cmd)){ drawCmd = "rectangle"; System.out.println("画矩形的监听器启动:"+drawCmd); }else if("画三角形(T)".equals(cmd)){ drawCmd = "triangle"; System.out.println("画三角形的监听器启动:"+drawCmd); } /******************************************新建文件*****************************/ else if("新建(N)".equals(cmd)){ //本地功能已经实现,网络功能待完善,在此不展示 } /******************************************保存文件*****************************/ else if("保存(S)".equals(cmd)){ //本地功能已经实现,网络功能待完善,在此不展示 } /******************************************打开文件*****************************/ else if("打开(O)".equals(cmd)){ //本地功能已经实现,网络功能待完善,在此不展示 } /******************************************退出操作*****************************/ else if("退出(E)".equals(cmd)){ System.out.println("退出的监听器启动"); System.out.println("程序已经关闭"); System.exit(0); } /******************************************关于信息*****************************/ else if("关于(A)".equals(cmd)){ System.out.println("关于的监听器启动"); JFrame aboutFrame = new JFrame("关于\"画板\""); aboutFrame.setSize(280,240); aboutFrame.setDefaultCloseOperation(2); aboutFrame.setResizable(false); aboutFrame.setLocationRelativeTo(null); aboutFrame.setLayout(new FlowLayout()); aboutFrame.setVisible(true); JLabel label = new JLabel(); //创建一个超链接 final JLabel la_url = new JLabel("博客:http://yacare.iteye.com"); //设置链接颜色为蓝色 la_url.setForeground(Color.BLUE); label.setText("<html><body>Certified by Internet Society<br>" + "网络画板服务器端 (本大爷专属)<br>@author YangKang<br>@version 1.0<br>" + "©Copyright 版权所有,山寨必究<br>本软件只供学习娱乐之用,严禁从事商业用途" + "<br><br>联系作者:<br>" + "QQ:1009425612<br>TEL:18942558998<br>" + "Addess:保密" + "</body></html>"); aboutFrame.add(label); aboutFrame.add(la_url); //将链接添加鼠标监听器 la_url.addMouseListener(new MouseAdapter() { //鼠标离开时,链接前景色变为橙色 @Override public void mouseExited(MouseEvent e) { la_url.setForeground(Color.ORANGE); } //鼠标进入时,链接前景色变成红色 @Override public void mouseEntered(MouseEvent e) { la_url.setForeground(Color.RED); } //鼠标点击超链接时,打开浏览器进入链接地址 @Override public void mouseClicked(MouseEvent e) { try { //定义链接地址 URI uri = new URI("http://yacare.iteye.com"); Desktop dtp = Desktop.getDesktop(); //是否支持此类和对象浏览 if(Desktop.isDesktopSupported()&&dtp.isSupported(Desktop.Action.BROWSE)){ //在浏览器中打开此链接 dtp.browse(uri); } } catch (Exception e1) { e1.printStackTrace(); } } }); } } }; /** * 网络画板通信模块,连接客户端 */ private void Conn2Client() { try{ //1.建立绑定在指定端口上的服务器对象 server = new ServerSocket(port); System.out.println("服务器创建成功"+this.port); //2.当有客户机连接时,等待方法就会返回,返回一个代表与客户端连接的对象 while(true){ //让服务器处于循环待机状态 client = server.accept();//可能会发生堵塞 //创建客户端的输出流 ous = client.getOutputStream(); dous = new DataOutputStream(ous); //创建客户端的输入流 ins = client.getInputStream(); dins = new DataInputStream(ins); System.out.println("Incoming"+client.getRemoteSocketAddress().toString()); //启动读取客户端数据的线程 this.start(); System.out.println("处理线程已启动,正处理登录操作!"); } }catch(Exception e1){ e1.printStackTrace(); } } /** * 重写父类run()方法,用来读取客户端的数据 */ public void run(){ //在线程run中调用处理连结的方法 readLineFromClient(dins); } /** * 将发送图形的代码封装到sendLine2Client方法中 * @param type 图形的类型 * @param 传入两点的坐标 */ public void sendLine2Client(int type,int x1,int y1,int x2,int y2){ try { dous.writeByte(type); //type 表示绘制图形类型 dous.writeInt(x1); dous.writeInt(y1); dous.writeInt(x2); dous.writeInt(y2); ous.flush(); //强制输出 System.out.println("向服务器发送直线成功"); } catch (IOException e) { e.printStackTrace(); } } /** * 读取客户端发过来的直线信息,接收并画在窗体上 */ private void readLineFromClient(DataInputStream dins) { try { while(true){ type = dins.readByte(); x1 = dins.readInt(); y1 = dins.readInt(); x2 = dins.readInt(); y2 = dins.readInt(); System.out.println("读取客户端发送来的图形数据成功,类型:"+type); //判断绘制图形的类型 if(type == 1){ //1表示画直线 //根据传入的坐标,调用绘制直线的方法来画直线 g.drawLine(x1,y1,x2,y2); }else if(type == 2){//2表示画椭圆 //根据传入的坐标,调用绘制椭圆的方法来画椭圆 int minX = Math.min(x1, x2); int minY = Math.min(y1, y2); g.drawOval(minX,minY,Math.abs(x2-x1),Math.abs(y2-y1)); }else if(type == 3){//3表示画矩形 //根据传入的坐标,调用绘制矩形的方法来画矩形 int minX = Math.min(x1, x2); int minY = Math.min(y1, y2); g.drawRect(minX,minY,Math.abs(x2-x1),Math.abs(y2-y1)); }else if(type == 4){//4表示画三角形 //根据传入的坐标,调用绘制直线的方法来画等腰三角形 g.drawLine(x1,y1,x2,y2); g.drawLine(x1,y1,x1*2-x2,y2); g.drawLine(x2,y2,x1*2-x2,y2); } } } catch (IOException e) { e.printStackTrace(); }finally { try { dins.close(); ins.close(); ous.close(); dous.close(); client.close(); }catch (Exception e2) { e2.printStackTrace(); } } } @Override public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { System.out.println("鼠标监听器得到命令:"+drawCmd); //获取鼠标按下时的坐标值 x1 = e.getX(); y1 = e.getY(); System.out.println("鼠标按下的坐标:"+"x1-->"+x1+",y1-->"+y1); } @Override public void mouseReleased(MouseEvent e) { //获取鼠标释放时的坐标值 x2 = e.getX(); y2 = e.getY(); System.out.println("鼠标松开的坐标:"+"x2-->"+x2+",y2-->"+y2); System.out.println("鼠标捕捉到的点坐标:x1-->"+x1+" y1-->"+y1+" x2-->"+x2+" y2-->"+y2); //根据命令,获取按下和释放的坐标,调用绘制直线的方法来画线/画圆 if(drawCmd.equals("null")){ JOptionPane.showMessageDialog(null, "请先选择绘图命令"); System.out.println("未指定画图命令,请选择画图类型"); System.out.println("**************************************"); }if(drawCmd.equals("line")){ //根据按下和释放的坐标,调用绘制直线的方法来画直线 g.drawLine(x1,y1,x2,y2); //将绘图数据传到客户端 type = 1; //1表示绘制图形为直线 sendLine2Client(type,x1,y1,x2,y2); System.out.println("画直线成功"); System.out.println("**************************************"); }if(drawCmd.equals("oval")){ //根据按下和释放的坐标,调用绘制椭圆的方法来画椭圆 int minX = Math.min(x1, x2); int minY = Math.min(y1, y2); g.drawOval(minX,minY,Math.abs(x2-x1),Math.abs(y2-y1)); //将绘图数据传到客户端 type = 2; //2表示绘制图形为椭圆 sendLine2Client(type,x1,y1,x2,y2); System.out.println("画椭圆成功"); System.out.println("**************************************"); }if(drawCmd.equals("rectangle")){ //根据按下和释放的坐标,调用绘制直线的方法来画矩形 g.drawLine(x1,y1,x2,y1); g.drawLine(x1,y1,x1,y2); g.drawLine(x1,y2,x2,y2); g.drawLine(x2,y1,x2,y2); //将绘图数据传到客户端 type = 3; //3表示绘制图形为矩形 sendLine2Client(type,x1,y1,x2,y2); System.out.println("画矩形成功"); System.out.println("**************************************"); }if(drawCmd.equals("triangle")){ //根据按下和释放的坐标,调用绘制直线的方法来画等腰三角形 g.drawLine(x1,y1,x2,y2); g.drawLine(x1,y1,x1*2-x2,y2); g.drawLine(x2,y2,x1*2-x2,y2); //将绘图数据传到客户端 type = 4; //3表示绘制图形为等腰三角形 sendLine2Client(type,x1,y1,x2,y2); System.out.println("画三角形成功"); System.out.println("**************************************"); } } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } }
相关推荐
Java聊天室是一个基于Java编程语言实现的简单在线通信系统,它允许用户通过客户端与服务器进行交互,发送和接收消息。这个项目通常会涉及到网络编程、多线程和面向对象设计等核心Java技术。 首先,我们要了解Java...
java类工具库项目源码.zip(教程+源代码+附上详细代码说明)。一款高含金量的java项目 一个功能丰富且易用的Java工具库,通过诸多实用工具类的使用,旨在帮助开发者快速、便捷地完成各类开发任务。 这些封装的工具...
以下是一个简单的Java代码实现冒泡排序: ```java public class BubbleSort { public static void main(String[] args) { int[] array = {5, 3, 8, 1, 2}; bubbleSort(array); for (int i : array) { System....
java 写的文件管理系统(带注释),具有如下功能(附上直接可运行的Myexplorer.jar 和 安装版本的封装MyExplorer_setup.exe文件) 2.3基本功能:(1)文件和目录的基本操作,比如文件和目录的创建、删除、复制、移动...
基于VUE的实战项目源码.zip(教程+源代码+附上详细代码说明)。一款高含金量的VUE项目 项目参考于网易云音乐PC版app,基本实现官方音乐播放、MV播放所有功能 项目代码齐全,教程详尽,有具体的使用说明,是个不错的...
神经网络模型源码.zip(教程+源代码+附上详细代码说明)。一款高含金量的神经网络模型项目,项目中基于python进行开发,所有的代码都附上相关的注释说明。 项目(高含金量项目)自发布受到广大开发者的一致好评,...
《Java Web图书管理系统详解》 Java Web图书管理系统是一款基于C/S(Client/Server)模式的软件应用,旨在高效地管理图书信息,实现图书的增删改查等操作。本系统采用了分层架构设计,将复杂的功能分解为逻辑层、...
跨平台性(Write Once, Run Anywhere): Java的代码可以在不同的平台上运行,只需编写一次代码,就可以在任何支持Java的设备上执行。这得益于Java虚拟机(JVM),它充当了代码和底层硬件之间的中介。 面向对象: ...
即可以在Java代码中调用C/C++等语言的代码或者在C/C++代码中调用Java代码。由于JNI是JVM规范的一部分,因此可以将我们写的JNI的程序在任何实现了JNI规范的Java虚拟机中运行。同时,这个特性使我们可以复用以前用C/...
本资源包提供了一个基于Java的解决方案,使用了ZXing库(Zebra Crossing)和Java 2D图形API(Graphics2D)来实现这些功能。以下是关于这些技术的详细解释: 1. **ZXing库**: ZXing,又称为“条形码扫描器”,是一...
本文将深入探讨“3D过滤软件附上代码”的相关知识点,主要关注3D MAX中的过滤技术及其应用。 3D MAX是一款由Autodesk公司开发的著名三维建模、动画和渲染软件,广泛应用于电影、游戏、建筑可视化等行业。3D过滤软件...
Java具有丰富的类库,可以方便地处理网络通信、数据库连接、图形用户界面(GUI)开发等各种任务。 在这个毕业设计中,学生可能使用了Java SE(标准版)作为基础,结合Java EE(企业版)的部分技术,如Servlet、JSP...
JSON-lib作为一个强大的Java JSON处理工具,使得在Java应用中处理JSON数据变得简单易行。无论是将Java对象转换为JSON字符串进行传输,还是从接收到的JSON数据中恢复Java对象,JSON-lib都提供了方便的API。在实际项目...
面向对象:Java全面支持面向对象的特性,如封装、继承和多态,使得代码更易于维护和扩展。 安全:Java提供了丰富的安全特性,如禁止指针运算、自动内存管理和异常处理机制,以减少程序错误和恶意攻击的可能性。 ...
网络安全大模型项目源码.zip(教程+源代码+附上详细代码说明)。一款高含金量的项目,经过验证可直接运行 项目的愿景是将人工智能技术引入网络安全领域,以提高网络防御的效率和效果。其使命是推动网络安全智能化,...
1.使用java发送 日程 会议邮件 可以达到安排别人日程预约的目的,代码如下。这个网上教程和多,但是如果已经发送了日程,又需要使用代码进行修改怎么办呢? 2.会议的修改和取消: 首先,发送安排时需要记录生成的...
《编译原理课程设计——Java实现C语言编译器》 在计算机科学领域,编译器扮演着至关重要的角色,它将高级编程语言转化为机器可理解的二进制代码。本项目聚焦于编译原理,以Java语言为工具,实现了C语言的编译器,...
S7-1200PLC使用SCL语言编程实现数控G代码指令编程控制(附上源程序)
matlab无人机编队仿真项目源码.zip(教程+源代码+附上详细代码说明)。一款高含金量的matlab项目,经过验证可直接运行 项目代码齐全,教程详尽,有具体的使用说明,是个不错的有趣项目。 项目(高含金量项目)自发布...
人脸识别检测opencv简单java实现要不是毕业好几年我都不舍得分享出来!!! CTRL+D收藏一下或者关注走一波-有你所需!不断更新! 其他相关下载,配套代码以及PPT。稳妥的小老弟 ...加载本地的OpenCV库,这样就可以用它...