1.实现图形、图片、信息的发送,首先写了一个服务器的界面,在界面上给按钮添加了ActionListener 的监听器,目的是为了写一个判断的标志区别画线,画圆及发送图片的功能.然而,服务器发送直线和圆我是另外创建了一个鼠标监听器MouseListener,每当释放鼠标的时候根据前面的判断标志画一条线或是或一个圆.
2.值得注意的是画完一条线或是画完一个圆后就发送出去.假如要是等着线或是圆都画完了才发送这就会出现问题,比如说服务器要判断到底什么时候才能画完线以及圆,还有一点就是画线和画圆与发送消息不同的地方时,在定义消息发送的时候我是定义的一个字节一个字节的发送,而在发送直线、圆的时候定义的是发送5个int,第一个int判断发送的图形,后面4个int是为了保证有两点坐标表实现画线画圆的操作.发送图片也是类似的操作,每次发送四个int,第一个int实现判断发送的是图片,第二个int发送的是颜色rgb=image.getRGB(i,j);,后面两个int实现画一个点.代码如下:
public void mouseReleased(MouseEvent e) { x2 = e.getX(); y2 = e.getY(); //判断画直线 if(type == 1){ g.drawLine(x1,y1,x2,y2);//画出一条直线 ChatList.sendIntMg(1);//服务器的信息为1发送一条直线 ChatList.sendIntMg(x1); ChatList.sendIntMg(y1); ChatList.sendIntMg(x2); ChatList.sendIntMg(y2); System.out.println("画直线的方法执行了!!!"); } //判断画圆 if(type == 2){ g.drawOval(x1,y1,Math.abs(x2-x1),Math.abs(y2-y1));//画一个圆 ChatList.sendIntMg(2);//服务器的信息为2发送一个圆 ChatList.sendIntMg(x1); ChatList.sendIntMg(y1); ChatList.sendIntMg(x2); ChatList.sendIntMg(y2); System.out.println("画圆的方法执行了!!!"); }
3.发送图片的方法如下:通过一个按钮先实现了将图片画到自定义的面板上,画好后执行的操作还是即刻发送
if(e.getActionCommand().equals("发图")){ System.out.println(e.getActionCommand()); try { BufferedImage image = ImageIO.read(new File("images/桌面.png"));//存入一张图片 System.out.println("图片存放了!"); int w = image.getWidth();//得到图片的宽度 int h = image.getHeight();//得到图片高度 //遍历图片上的每一个像素点 for(int i=0;i<w;i++){ for(int j=0;j<h;j++){ rgb = image.getRGB(i, j);//图片上去的像素点 Color cl = new Color(rgb); g.setColor(cl);//画笔的颜色 //画图片其实就是画点 g.drawLine(i, j, i, j); //画出图片后就进行发送 ChatList.sendIntMg(4); ChatList.sendIntMg(i); ChatList.sendIntMg(j); ChatList.sendIntMg(rgb); } } } catch (IOException e1) { e1.printStackTrace(); } }
4.在图形以及信息发送之前首要的是给服务器定义一些方法,总的来说大的发面无非就是接收消息以及发送消息了.
(1)当点击服务器上的端口按钮时,实现服务器接收消息
//服务器接收消息的 方法 public void acceptMsg(){ //服务器接收消息 String strread = readString(ins); while(!strread.equals("exit")){ System.out.println("服务器: \r\n"+strread); String sin = "客户端: \r\n"+strread;//客户端收到的消息 byte [] byt = sin.getBytes(); ChatList.sendMsg(byt); jta.setText("客户端: \r\n"+sin); strread = readString(ins); }
(2)服务器发送消息,每次发送一个字节
//服务器群发消息的方法 public void sendAll(byte [] by){ try { dao.write(by); dao.flush(); } catch (IOException e) { e.printStackTrace(); } }
(3)服务器读取直线,其实质就是每次都读到一个int值
//服务器接收直线 public void readLine(){ try { x1 = dai.readInt(); y1 = dai.readInt(); x2 = dai.readInt(); y2 = dai.readInt(); g.drawLine(x1,y1,x2,y2); } catch (IOException e) { e.printStackTrace(); } }
(4)服务器接收到画圆的方法与画线的方法类似,也是每次读到一个int字节
//服务器接收圆的方法 public void readCycle(){ try { x1 = dai.readInt(); y1 = dai.readInt(); x2 = dai.readInt(); y2 = dai.readInt(); g.drawOval(x1,y1,Math.abs(x2-x1),Math.abs(y2-y1)); } catch (IOException e) { e.printStackTrace(); } }
(5)服务器读取到发送图片的方法
//定义接收图片的方法 public void readpicture(){ try { i = dai.readInt(); j = dai.readInt(); //画图片 g.drawLine(i,j,i,j); } catch (IOException e) { e.printStackTrace(); } }
(6)既然有了接收int相当于每次读到四个字节的方法,当然要有发送int的方法了
//定义一个服务器发int的方法 public void sendInt(int flag){ try { dao.writeInt(flag); System.out.println("发送flag:"+flag); dao.flush(); } catch (IOException e) { e.printStackTrace(); } }
(7)为了简便期间以及便易其他地方调用最后定义了一个方法将上述方法包装到一个方法里面
//定义一个服务器与客户端连接的方法 public void towork(java.net.Socket client){ try { //获取输入输出流 ins = client.getInputStream(); ous = client.getOutputStream(); dai = new DataInputStream(ins);//创建一个读入数据的对象 dao = new DataOutputStream(ous);//创建一个写数据的对 //设置判断标识符 int flag = dai.read(); while(true){ System.out.println("读出的flag是: "+flag); //当读到1的时候画线 if(flag == 1){ readLine(); } //当读到2的时候画圆 if(flag == 2){ readCycle(); } //当读到3的时候发送消息 if(flag == 3} acceptMsg(); } if(flag == 4){ readpicture(); } flag = dai.readInt();//读取多个信息 } } catch (IOException e) { e.printStackTrace(); } }
5.自己的理解就是其实当服务器与客户端进行连接之后就相当于可以把客户端也看做成服务器所以说,客户端界面的方法与服务器的方法是类似的这里就不一一列举了.不过,我单独用另外的一个类定义了客户端的方法了.与服务器的方法有一点区别的是我定义了一个客户端的连接方法,实现如下:
//定义服务器与客户端连接的方法 public boolean Connect(){ try { //创建客户端与服务器连接的对象 java.net.Socket soclient = new java.net.Socket(this.ip,this.port); System.out.println("客户端与服务器连接成功了!!!"); //获取输入输出流 ins = soclient.getInputStream(); ous = soclient.getOutputStream(); //数据输入输出流 dai = new DataInputStream(ins); dao = new DataOutputStream(ous); System.out.println("Connect方法执行了!!!"); return true; } catch (Exception e) { e.printStackTrace(); } return false }
6.在此,附上服务器界面的代码客户端的于此类似
package cgh20130730通信发送图形; import java.awt.Color; 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.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JTextField; /** * 创建一个服务器界面类继承自JFrame * @author Allen * */ public class ServerUI extends JFrame { /** * 程序的入口主函数 * @param args */ public static void main(String[] args) { //创建对象调用窗体初始化的方法 ServerUI sr = new ServerUI(); sr.INtUI(); } private int x1,y1; private int x2, y2;//坐标属性 private int nport; private int type; private DataInputStream dai; private DataOutputStream dao; private Graphics g; private int rgb; //初始化一个窗体 public void INtUI() { this.setTitle("服务器"); this.setSize(700,650); this.setLocationRelativeTo(null); this.setResizable(false); //设置窗体的流式布局 this.setLayout(new FlowLayout()); //创建按钮对象 JButton jbu = new JButton("端口"); JButton jbu1 = new JButton("发送"); //创建文本框对象 final JTextField jte = new JTextField(30); final JTextField jte1 = new JTextField(30); //创建一个纯文本多行区域 final JTextArea jta = new JTextArea(); jta.setPreferredSize(new Dimension(650,200)); //添加到窗体 this.add(jbu); this.add(jte); this.add(jbu1); this.add(jte1); this.add(jta); //创建一个面板对象 JPanel jpa = new JPanel(); jpa.setPreferredSize(new Dimension(650,350)); jpa.setBackground(Color.GRAY); JButton jbu2 = new JButton("画线"); JButton jbu3 = new JButton("画圆"); JButton jbu4 = new JButton("发图"); jpa.add(jbu2); jpa.add(jbu3); jpa.add(jbu4); //添加面板 this.add(jpa); //显示窗体是否可见 this.setVisible(true); //取得面板上的画布 final Graphics g = jpa.getGraphics(); //动作监听器 ActionListener action = new ActionListener(){ public void actionPerformed(ActionEvent e) { if(e.getActionCommand().equals("端口")){ nport = Integer.parseInt(jte.getText()); //创建一个服务器类的对象 Server ser = new Server(9007,jta,dao,g); ser.start(); System.out.println("端口号是:==="+nport); } if(e.getActionCommand().equals("发送")){ String strn = jte1.getText(); jta.append("服务器: \r\n"+strn+"\r\n"); ChatList.sendMsg(strn.getBytes()); ChatList.sendIntMg(3); //发完后清空文本 jte1.setText(""); } /* * 画线以及画圆的协议 */ if(e.getActionCommand().equals("画线")){ type = 1; } if(e.getActionCommand().equals("画圆")){ type = 2; } if(e.getActionCommand().equals("发图")){ System.out.println(e.getActionCommand()); try { BufferedImage image = ImageIO.read(new File("images/桌面.png"));//存入一张图片 System.out.println("图片存放了!"); int w = image.getWidth();//得到图片的宽度 int h = image.getHeight();//得到图片高度 //遍历图片上的每一个像素点 for(int i=0;i<w;i++){ for(int j=0;j<h;j++){ rgb = image.getRGB(i, j);//图片上去的像素点 Color cl = new Color(rgb); g.setColor(cl);//画笔的颜色 //画图片其实就是画点 g.drawLine(i, j, i, j); //画出图片后就进行发送 ChatList.sendIntMg(4); ChatList.sendIntMg(i); ChatList.sendIntMg(j); ChatList.sendIntMg(rgb); } } } catch (IOException e1) { e1.printStackTrace(); } } } }; jbu.addActionListener(action); jbu1.addActionListener(action); jbu2.addActionListener(action); jbu3.addActionListener(action); jbu4.addActionListener(action); //面板上添加监听器 MouseListener mouse = new MouseListener(){ public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { x1 = e.getX(); y1 = e.getY(); } public void mouseReleased(MouseEvent e) { x2 = e.getX(); y2 = e.getY(); //判断画直线 if(type == 1){ g.drawLine(x1,y1,x2,y2);//画出一条直线 ChatList.sendIntMg(1);//服务器的信息为1发送一条直线 ChatList.sendIntMg(x1); ChatList.sendIntMg(y1); ChatList.sendIntMg(x2); ChatList.sendIntMg(y2); System.out.println("画直线的方法执行了!!!"); } //判断画圆 if(type == 2){ g.drawOval(x1,y1,Math.abs(x2-x1),Math.abs(y2-y1));//画一个圆 ChatList.sendIntMg(2);//服务器的信息为2发送一个圆 ChatList.sendIntMg(x1); ChatList.sendIntMg(y1); ChatList.sendIntMg(x2); ChatList.sendIntMg(y2); System.out.println("画圆的方法执行了!!!"); } } }; jpa.addMouseListener(mouse);//面板添加监听器 } }
7.简单总结一下该过程中遇到的问题:
(1)服务器发送直线和圆经过测试没有问题可以发送出去,但是在客户端一直显示不出来,原来是自己在定义客户端接收方法的时候出现了一些小问题
(2)服务器可以向客户端发送消息,而反过来的操作就没法实现,最后发现了服务器的方法里面,自己吧read()字节的方法,写成而来readInt()了,因为每次发送的时候自己定义的是发送一个字节
(3)在写完这个程序的时候还有不足的地方就是还没有实现客户端发送直线圆及图片的服务器的方法.
(4)到此结束,希望大家能够多多指正代码中的不足......
相关推荐
实验室管理系统 微信小程序+SSM毕业设计 源码+数据库+论文+启动教程 项目启动教程:https://www.bilibili.com/video/BV1BfB2YYEnS
基于java的苹果网吧计费管理系统设计与实现.docx
纸中世界-跳跃游戏.sb3
本操作指导用于在 ENA 系列网络分析仪 E5080B 上自定义校准件。目前 Keysight 网络分析仪的 PNA 系列 N52xxB、P50xx 系列、P937x 系列、PXI 板卡式网分以及 ENA 系列的 E5080B、E5081B 的操作界面均统一到如下界面,操作方式相同。
调查海域浮游动物各类群栖息密度的空间分布表格.docx
本项目“高校毕业生就业管理系统”是一套基于SSM框架(Spring+SpringMVC+MyBatis)精心开发的Java Web应用,旨在为高校毕业生、高校就业指导部门以及企业用户提供一个高效、便捷的就业信息管理平台。 系统主要功能包括:学生用户可以查看和发布个人简历,搜索并筛选合适的工作岗位,申请心仪的职位;企业用户可以发布招聘信息,筛选和查看应聘者的简历,进行面试邀请等操作;高校就业指导部门则可以对学生的就业情况进行统计和分析,以更好地提供就业指导服务。 此外,系统采用了B/S架构,用户只需通过浏览器即可访问,无需安装客户端软件,方便快捷。数据库设计合理,数据存储安全,系统性能稳定。 本项目的开发,不仅为计算机相关专业的学生提供了一个实践SSM框架的好机会,帮助他们更好地理解和掌握Java Web开发技术,还能有效提升高校毕业生的就业效率和质量。
电影剪辑 笔记MoviePy 最近升级到 v2.0,引入了重大的重大变化。有关如何更新 v2.0 代码的更多信息,请参阅本指南。MoviePy(在线文档在此处)是一个用于视频编辑的 Python 库剪切、连接、插入标题、视频合成(又名非线性编辑)、视频处理和创建自定义效果。MoviePy 可以读取和写入所有最常见的音频和视频格式,包括 GIF,并且可以在 Windows/Mac/Linux 上运行,并搭载 Python 3.9+。例子在此示例中,我们打开一个视频文件,选择 10 到 20 秒之间的子剪辑,在屏幕中心添加标题,然后将结果写入新文件# Import everything needed to edit video clipsfrom moviepy import *# Load file example.mp4 and keep only the subclip from 00:00:10 to 00:00:20clip = VideoFileClip("long_examples/example2.mp4").with_subcl
基于java的视频播放器系统设计与实现.docx
基于java的车辆出租管理系统设计与实现.docx
mqtt等协议的pcap文件
学习python
修木工施工规范及流程.docx
适用于 Windows/Linux 和 Python 3 (3.5/3.6/3.7) 的 Tensorflow Faster R-CNNtf-faster-rcnn使用 Python 3 在 Windows 和 Linux 上使用 Tensorflow Faster R-CNN这是在 Windows 和 Linux 上编译 Faster R-CNN 的分支。它深受这里和这里的出色工作的启发。目前,此存储库支持 Python 3.5、3.6 和 3.7。感谢@morpheusthewhite请注意我没有时间或意图修复此分支的所有问题,因为我不将其用于商业用途。我创建此分支只是为了好玩。如果您想做出任何承诺,我们非常欢迎。Tensorflow 已经发布了一个对象检测 API。请参考它。https: //github.com/tensorflow/models/tree/master/research/object_detection如何使用此分支安装 tensorflow,最好是 GPU 版本。按照说明操作。如果没有安装 GPU 版本,则需要注释掉代码中的所有 GP
Python是一种高级、解释型、面向对象的编程语言,以其简洁的语法、强大的功能和广泛的应用领域而著称。它无需事先编译,代码在运行时逐行解释执行,提供了极大的灵活性和快速开发的能力。Python支持多种数据类型,包括整数、浮点数、字符串、布尔值、列表、元组、字典和集合等,以及丰富的操作符和流程控制结构,使得开发者可以编写出复杂且灵活的代码。 Python拥有一个广泛的标准库,涵盖了文件操作、网络通信、文本处理、正则表达式、数学运算等多个领域,为开发者提供了大量的模块和函数。此外,Python还拥有丰富的第三方库,如NumPy、Pandas、Matplotlib等用于数据分析和可视化的库,以及Django、Flask等用于Web开发的框架,这些库和框架进一步扩展了Python的应用领域和功能。 Python在Web开发、数据科学、人工智能、自动化运维和游戏开发等多个领域都有广泛的应用。在Web开发方面,Python提供了Django和Flask等强大的Web框架,使得开发者可以轻松地开发出各种Web应用和网站。在数据科学领域,Python是数据科学家的首选工具,其强大的数据处理能力和丰
本项目是基于Python语言开发的西西家居全屋定制系统,旨在为家居行业提供一个高效、智能的定制解决方案。项目涵盖了从客户需求分析、设计方案生成、材料选购到最终订单生成的全过程,力求实现家居定制的数字化和智能化。 在主要功能方面,系统具备强大的客户管理模块,能够详细记录和分析客户的定制需求。设计模块则采用先进的三维建模技术,为客户提供直观、真实的家居设计方案预览。此外,系统还整合了丰富的材料数据库,方便客户根据自身喜好和预算进行材料选择。 框架方面,项目采用了B/S架构,确保了系统的稳定性和可扩展性。后端使用Python的Django框架,前端则结合了HTML、CSS和JavaScript等技术,实现了用户界面的友好和响应速度。 开发此项目的目的,不仅是为了满足家居行业对个性化定制的需求,也为计算机相关专业的学生提供了一个实践和学习的平台,有助于提升他们的实际开发能力。
Binance公共API连接器Python 这是一个轻量级库,可作为Binance 公共 API的连接器支持的 API/api/*/sapi/*现货 Websocket 市场动态现货用户数据流现货 WebSocket API包含测试用例和示例可定制的基本 URL、请求超时和 HTTP 代理可以显示响应元数据安装pip install binance-connector文档https://binance-connector.readthedocs.ioRESTful API使用示例from binance.spot import Spotclient = Spot()# Get server timestampprint(client.time())# Get klines of BTCUSDT at 1m intervalprint(client.klines("BTCUSDT", "1m"))# Get last 10 klines of BNBUSDT at 1h intervalprint(client.k
Aptana是一个非常强大,开源,JavaScript-focused的AJAX开发IDE。 Aptana的特点包括: 1JavaScript,HTML,CSS语言的Code Assist功能。 2Outliner(大纲):显示JavaScript,HTML和CSS的代码结构。
学习自律养成小程序 微信小程序+SSM毕业设计 源码+数据库+论文+启动教程 项目启动教程:https://www.bilibili.com/video/BV1BfB2YYEnS
认知能力评估表.docx
数学建模学习资料 粒子群算法 先进算法讲义.pdf