ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

UDP通信和GUI实现简单的窗体通信

2019-07-28 18:40:55  阅读:173  来源: 互联网

标签:UDP GUI 通信 private public catch new e1 void


文章目录

概述

本文是使用GUI创建了这么一个对话窗体,其中涉及的知识有GUI(窗体,键盘监听等)和一些基础知识(多线程,网络编程(UDP通信)等)。下面首先来说一下UDP通信。(至于为什么不说GUI,是因为GUI无论实在工作中还是面试中都不会用到,因此在这里就不阐述GUI了!)

网络编程

众所周知网络的产生拉近了人与人之间的距离,从最开始的简单通信到今天,而通信需要一定的规则协议,我们把这种协议称之为通信协议。此外网络编程知识中的:IP,端口号等我在这里就不在过多叙述,一个URL(俗称网址)的组成必定少不了它们!这里主要针对于本文去稍加阐述一下UDP和TCP两种协议!

基于传输层的API

TCP

概念

TCP为传输控制协议,通常是一个面向连接的协议,它可以把数据当做双向字节流进行交换以便于达到传输的目的。主要用于文件下载,如我们常用的迅雷等软件。

如何实现通信

ServerSocket类和Socket(套接字)类结合IO流的知识来实现通信:会用到ServerSocket中的accept()方法和Socket中的获取输入输出流相关方法等)。

UDP

概念

UDP为用户数据包协议,是一种面向无连接的协议,一次性发送多个数据包,也可以接受多个数据包。它只负责发送,不负责是否接收到,因此效率高的同时也不安全!

如何实现通信

DatagramSocket和DatagramPacket两个类去实现通信,会用到DatagramSocket中的send()和receive()方法及DatagramPacket中的getData()和getLength()方法。

二者区别

TCP :面向连接,适用于传输大量数据,效率较低,传输安全。
UDP:面向无连接,适用于传输少量数据,效率高,传输不安全。
二者都可以用来实现通信!!!

窗体通信

结构

上中下三块区域(panel),四个按钮,一个地址区域!
在这里插入图片描述

创建结构相关代码

public void centerPanel() {
		Panel center=new Panel();//创建中间的panel
		viewText = new TextArea();
		sendText = new TextArea(5,1);
		center.setLayout(new BorderLayout());//设置为边界布局管理器
		center.add(sendText,BorderLayout.SOUTH);//发送的文本区域放在下边
		center.add(viewText,BorderLayout.CENTER);//显示文本区域放在中间
		viewText.setEditable(false);//设置上panel不能编辑
		viewText.setBackground(Color.WHITE);//设置显示区域背景颜色
		sendText.setFont(new Font("xxx", Font.PLAIN, 15));//设置发送区域的文字类型,样式,大小
		viewText.setFont(new Font("xxx", Font.PLAIN, 15));//设置显示区域的文字类型,样式,大小
		this.add(center,BorderLayout.CENTER);
	}


public void xiaPanel() {
	Panel xia=new Panel();//创建下面的panel
	tf = new TextField(15);
	tf.setText("127.0.0.1");
	send = new Button("发送");
	log = new Button("记录");
	clear = new Button("清屏");
	shake = new Button("震动");
	
	xia.add(tf);
	xia.add(send);
	xia.add(log);
	xia.add(clear);
	xia.add(shake);
	this.add(xia,BorderLayout.SOUTH); 
}

按钮功能代码(GUI监听)

	private void event() {
			this.addWindowListener(new WindowAdapter() {
				@Override
				public void windowClosing(WindowEvent e) {
					try {
						socket.close();
						bw.close();
					} catch (Exception e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					System.exit(0);
				}
			});
			//设置监听
			send.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent e) {
					try {
						try {
							send();
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
					} catch (Exception e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					
				}
			});
			log.addActionListener(new ActionListener() {//记录
				
				@Override
				public void actionPerformed(ActionEvent e) {
					try {
						logFile();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					
				}
			});
			
			clear.addActionListener(new ActionListener() {//清屏
				
				@Override
				public void actionPerformed(ActionEvent e) {
					viewText.setText("");
					
				}
			});
			
			shake.addActionListener(new ActionListener() {//震动
				
				@Override
				public void actionPerformed(ActionEvent e) {
					try {
						send(new byte [] {-1},tf.getText());
					} catch (Exception e1) {
					
						e1.printStackTrace();
					}
					
				}
			});
			sendText.addKeyListener(new KeyAdapter() {//键盘监听
				@Override
				public void keyReleased(KeyEvent e) {
					if(e.getKeyCode()==KeyEvent.VK_ENTER) {//回车快捷键发送
						try {
							send();
						} catch (Exception e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
					}
				}
			});
		}

private void shake() {
		int x=this.getLocation().x;//获取横坐标位置
		int y=this.getLocation().y;//获取纵坐标位置
		for(int i=0;i<20;i++) {
		//设置横纵坐标
		try {
			this.setLocation(x+20, y+20);
			Thread.sleep(20);
			this.setLocation(x+20, y-20);
			Thread.sleep(20);
			this.setLocation(x-20, y+20);
			Thread.sleep(20);
			this.setLocation(x-20, y-20);
			Thread.sleep(20);
			this.setLocation(x, y);
		} catch (InterruptedException e) {
			
			e.printStackTrace();
		}
		}
	}
	
	private void logFile() throws IOException {
		bw.flush();  //刷新缓冲区
		FileInputStream fis=new FileInputStream("config.txt");
		//内存中创建缓冲区
		ByteArrayOutputStream baos=new ByteArrayOutputStream();
		
		int len;
		byte [] b=new byte[8192];
		while((len=fis.read(b))!=-1) {
			baos.write(b, 0, len);
		}
		
		String str=baos.toString();  //内存中的内容转换成字符串
		viewText.setText(str);
		
		fis.close();
	}
	
	private void send(byte [] b,String ip) throws Exception {
		DatagramPacket packet=new DatagramPacket(b, b.length,InetAddress.getByName(ip),9999);
		socket.send(packet);    //发送数据
	}
	private void send() throws Exception {
		String msg=sendText.getText();//获取发送区域的内容
		String ip=tf.getText();//获取ip地址
		ip=ip.trim().length()==0?"255.255.255.255":ip;
		send(msg.getBytes(),ip);
		
		String time=getCurrentTime();//获取当前时间
		String str = time+" 我对:"+(ip.equals("255.255.255.255")?"所有人":ip)+"说\r\n"+msg+"\r\n\r\n";
		viewText.append(str);//文本信息显示到显示区域
		bw.write(str);		//将信息写到数据库(文本文档)中
		sendText.setText("");//文本区域进行清除
		
	
		
	}

	private String getCurrentTime() {
		Date d=new Date();//创建当前日期对象
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
		
		return sdf.format(d);//时间格式化
				
	}
	private class Receive extends Thread{ //接收和发送要同时进行,所以要定义成多线程的(内部类)
	@Override
	public void run() {
		try {
			DatagramSocket socket=new DatagramSocket(9999);
			DatagramPacket packet=new DatagramPacket(new byte[8192], 8192);
			while(true) {
			socket.receive(packet);//接收信息
			byte [] b=packet.getData();//获取数据
			int len=packet.getLength();//获取有效数据
			if(b[0]==-1&&len==1) {		//如果数组第一个是-1且长度是1就调用自己的shake方法
				shake();
				continue;
			}
			String msg=new String(b,0,len);//转换成字符串
			String time=getCurrentTime();//获取当前时间
			String ip=packet.getAddress().getHostAddress();//获取ip地址
			String str = time+" "+ip+" 对我说:\r\n"+msg+"\r\n\r\n";
			viewText.append(str);
			bw.write(str);
			}
		} catch (Exception e) {
			
			e.printStackTrace();
		}
	}
}

在这里插入图片描述
在这里插入图片描述

完整代码

public class TestGUIChat extends Frame{
	private TextField tf;
	private Button send;
	private Button log;
	private Button clear;
	private Button shake;
	private TextArea viewText;
	private TextArea sendText;
	private DatagramSocket socket;
	private BufferedWriter bw;

public TestGUIChat() {
	init();
	xiaPanel();
	centerPanel();
	event();
	
}


private void event() {
	this.addWindowListener(new WindowAdapter() {
		@Override
		public void windowClosing(WindowEvent e) {
			try {
				socket.close();
				bw.close();
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			System.exit(0);
		}
	});
	//设置监听
	send.addActionListener(new ActionListener() {
		
		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				try {
					send();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}
	});
	log.addActionListener(new ActionListener() {//记录
		
		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				logFile();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}
	});
	
	clear.addActionListener(new ActionListener() {//清屏
		
		@Override
		public void actionPerformed(ActionEvent e) {
			viewText.setText("");
			
		}
	});
	
	shake.addActionListener(new ActionListener() {//震动
		
		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				send(new byte [] {-1},tf.getText());
			} catch (Exception e1) {
			
				e1.printStackTrace();
			}
			
		}
	});
	sendText.addKeyListener(new KeyAdapter() {//键盘监听
		@Override
		public void keyReleased(KeyEvent e) {
			if(e.getKeyCode()==KeyEvent.VK_ENTER) {//回车快捷键发送
				try {
					send();
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}
	});
}

private void shake() {
	int x=this.getLocation().x;//获取横坐标位置
	int y=this.getLocation().y;//获取纵坐标位置
	for(int i=0;i<20;i++) {
	//设置横纵坐标
	try {
		this.setLocation(x+20, y+20);
		Thread.sleep(20);
		this.setLocation(x+20, y-20);
		Thread.sleep(20);
		this.setLocation(x-20, y+20);
		Thread.sleep(20);
		this.setLocation(x-20, y-20);
		Thread.sleep(20);
		this.setLocation(x, y);
	} catch (InterruptedException e) {
		
		e.printStackTrace();
	}
	}
}

private void logFile() throws IOException {
	bw.flush();  //刷新缓冲区
	FileInputStream fis=new FileInputStream("config.txt");
	//内存中创建缓冲区
	ByteArrayOutputStream baos=new ByteArrayOutputStream();
	
	int len;
	byte [] b=new byte[8192];
	while((len=fis.read(b))!=-1) {
		baos.write(b, 0, len);
	}
	
	String str=baos.toString();  //内存中的内容转换成字符串
	viewText.setText(str);
	
	fis.close();
}

private void send(byte [] b,String ip) throws Exception {
	DatagramPacket packet=new DatagramPacket(b, b.length,InetAddress.getByName(ip),9999);
	socket.send(packet);    //发送数据
}
private void send() throws Exception {
	String msg=sendText.getText();//获取发送区域的内容
	String ip=tf.getText();//获取ip地址
	ip=ip.trim().length()==0?"255.255.255.255":ip;
	send(msg.getBytes(),ip);
	
	String time=getCurrentTime();//获取当前时间
	String str = time+" 我对:"+(ip.equals("255.255.255.255")?"所有人":ip)+"说\r\n"+msg+"\r\n\r\n";
	viewText.append(str);//文本信息显示到显示区域
	bw.write(str);		//将信息写到数据库(文本文档)中
	sendText.setText("");//文本区域进行清除
	

	
}

private String getCurrentTime() {
	Date d=new Date();//创建当前日期对象
	SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
	
	return sdf.format(d);//时间格式化
			
}


public void centerPanel() {
	Panel center=new Panel();//创建中间的panel
	viewText = new TextArea();
	sendText = new TextArea(5,1);
	center.setLayout(new BorderLayout());//设置为边界布局管理器
	center.add(sendText,BorderLayout.SOUTH);//发送的文本区域放在下边
	center.add(viewText,BorderLayout.CENTER);//显示文本区域放在中间
	viewText.setEditable(false);//设置上panel不能编辑
	viewText.setBackground(Color.WHITE);//设置显示区域背景颜色
	sendText.setFont(new Font("xxx", Font.PLAIN, 15));//设置发送区域的文字类型,样式,大小
	viewText.setFont(new Font("xxx", Font.PLAIN, 15));//设置显示区域的文字类型,样式,大小
	this.add(center,BorderLayout.CENTER);
}


public void xiaPanel() {
	Panel xia=new Panel();//创建下面的panel
	tf = new TextField(15);
	tf.setText("127.0.0.1");
	send = new Button("发送");
	log = new Button("记录");
	clear = new Button("清屏");
	shake = new Button("震动");
	
	xia.add(tf);
	xia.add(send);
	xia.add(log);
	xia.add(clear);
	xia.add(shake);
	this.add(xia,BorderLayout.SOUTH); 
	
}


public void init() {//初始化
	this.setLocation(500, 50);
	this.setSize(400, 600);
	new Receive().start();//开启线程
	try {
		socket = new DatagramSocket();
		bw=new BufferedWriter(new FileWriter("config.txt",true));//追加不是覆盖
	} catch (Exception e) {
		
		e.printStackTrace();
	}
	this.setVisible(true);
}

private class Receive extends Thread{ //接收和发送要同时进行,所以要定义成多线程的(内部类)
	@Override
	public void run() {
		try {
			DatagramSocket socket=new DatagramSocket(9999);
			DatagramPacket packet=new DatagramPacket(new byte[8192], 8192);
			while(true) {
			socket.receive(packet);//接收信息
			byte [] b=packet.getData();//获取数据
			int len=packet.getLength();//获取有效数据
			if(b[0]==-1&&len==1) {		//如果数组第一个是-1且长度是1就调用自己的shake方法
				shake();
				continue;
			}
			String msg=new String(b,0,len);//转换成字符串
			String time=getCurrentTime();//获取当前时间
			String ip=packet.getAddress().getHostAddress();//获取ip地址
			String str = time+" "+ip+" 对我说:\r\n"+msg+"\r\n\r\n";
			viewText.append(str);
			bw.write(str);
			}
		} catch (Exception e) {
			
			e.printStackTrace();
		}
	}
}
public static void main(String[] args) {
	new TestGUIChat();
}

}

总结

本文章为java初学者编写,希望对您有所帮助,不足之处请见谅!勿喷!
个人在求知的道路上前进着,如不嫌弃,可携手并进!
每周一篇,尽自己能力写好每一篇文章!希望得到大佬们的建议!

标签:UDP,GUI,通信,private,public,catch,new,e1,void
来源: https://blog.csdn.net/qq_45398309/article/details/97616701

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有