Java Socket以及界面动态加载的简单使用
2017-12-17 10:32
363 查看
因为Java的实验最后要做一个简单的聊天室,所以需要用到socket通信,但是书上并没有涉及这方面,所以在这里把做的过程中遇到的一些问题以及在网上找到的一些解决的办法做一下记录。
1. 创建Socket与SocketServer
socket 的创建有很多中方法,常用的方法有:
,Socket("localhost",1024);
在确定端口号的时候,如果不确定使用哪个端口号,可以使用一个循环,逐个测试:
2. socket 通信处理
因为在通信的时候,需要发送多条消息,所以我想要在用户注销时才关闭socket 连接,但是serversocket一般的判断是否有待接收的数据与读取数据的方法是先判断available ,之后读取的时候使用BufferedReader 判断是否read 到的为null。而如果想让server端的read读到null ,则发送端需要关闭连接才行。所以我使用一个自定义的消息结束标志EOF,用于表示此次消息发送的结束:
首先判断是否有待取的数据:
while(inputstream.available() == 0){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
之后从输入流中读取数据:
BufferedReader reader = new BufferedReader(new InputStreamReader(inputstream));
System.out.println("服务器:读取数据");
StringBuffer data = new StringBuffer(); //存储本次连接接收的数据
String info;
while((info = reader.readLine()) != null && !(info.equals("EOF"))){
data.append(info);
data.append("\n");
} 3. 如何关闭serversocket
因为serversocket的accept()方法是阻塞的,所以即使使用标志位通过while判断结束也不行。所以使用ServerSocket 的setSoTimeout() 方法,为ServerSocket的accept指定时长:
不过上面的方法会抛出IO异常,需要捕获该异常,不过不影响使用。
4. 界面的动态加载
实现界面的动态加载,如果是增加控件,我是先将jpanel 中的控件先保存到一个ArrayList中,之后将面板清空,最后加上之前保存的控件以及新加入的控件。在之前的操作完成后,使用invalidate(),validate(),repaint() 方法更新,最后使用的那三个用来更新界面的是参考了网上的一个方法。
下面是部分代码实现:
ArrayList<JCheckBox> checkBoxs = new ArrayList<JCheckBox>();
JLabel tipLable = new JLabel(); //用户面板的提示文字标签
int componentcount = clientUI.getPanelUsers().getComponentCount();
for(int i=0;i<componentcount;++i){
Object obj = clientUI.getPanelUsers().getComponent(i);
if(obj instanceof JCheckBox){
checkBoxs.add((JCheckBox)obj);
}else if(obj instanceof
4000
JLabel){
tipLable = (JLabel)obj;
}
}
clientUI.getPanelUsers().removeAll(); //清除
clientUI.getPanelUsers().add(tipLable); //先增加提示文字标签
for(int i=0;i<checkBoxs.size();++i){
clientUI.getPanelUsers().add(checkBoxs.get(i));
}
System.out.println("客户端:新增用户 " + receivedData);
//在客户端界面上显示新用户进入的消息
//TODO
clientUI.getTextArea().setFont(new Font("Arial",Font.ITALIC,10));
clientUI.getTextArea().append("New User: " + receivedData + "Coming in\n");
clientUI.getTextArea().setFont(new Font("楷体",Font.PLAIN,20));
// clientUI.getTextArea().setFont(new Font());
JCheckBox jcheckBox = new JCheckBox(receivedData,false);
jcheckBox.setSize(80, 80);
clientUI.getPanelUsers().add(jcheckBox);
clientUI.getPanelUsers().invalidate();
clientUI.getPanelUsers().validate();
clientUI.getPanelUsers().repaint(); 如果是删除某个控件的话,可以简单一些,直接根据条件判断需要删除哪些,之后直接使用jpanel 的remove()方法,最后使用那三个方法更新。不知道需不需要考虑删除后控件的位置问题,我使用的布局是BoxLayout,Y轴布局,没有发现问题。
参考:
解决java获取panel中所有控件的问题 - CSDN博客: http://blog.csdn.net/u012505618/article/details/50149097
怎样在JPanel中添加删除组件????????-CSDN论坛: http://bbs.csdn.net/topics/60450227
如何关闭一个正在accept的ServerSocket? - CSDN博客: http://blog.csdn.net/qiuhan/article/details/6085176
1. 创建Socket与SocketServer
socket 的创建有很多中方法,常用的方法有:
Socket(InetAddress address, int port),Socket(String host, int port)。前面一个是通过制定ip 地址与端口号创建一个socket,后者是通过主机名与端口号创建一个socket。比如:Socket(getByName("localhost"),1024)
,Socket("localhost",1024);
在确定端口号的时候,如果不确定使用哪个端口号,可以使用一个循环,逐个测试:
for(int i=1024;i<65535;++i){ try { socket = new Socket("localhost",i); break; } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }在创建ServerSocket 的时候,我是直接将它的端口号指定为1024: serverSocket = new ServerSocket(1024);
2. socket 通信处理
因为在通信的时候,需要发送多条消息,所以我想要在用户注销时才关闭socket 连接,但是serversocket一般的判断是否有待接收的数据与读取数据的方法是先判断available ,之后读取的时候使用BufferedReader 判断是否read 到的为null。而如果想让server端的read读到null ,则发送端需要关闭连接才行。所以我使用一个自定义的消息结束标志EOF,用于表示此次消息发送的结束:
首先判断是否有待取的数据:
while(inputstream.available() == 0){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
之后从输入流中读取数据:
BufferedReader reader = new BufferedReader(new InputStreamReader(inputstream));
System.out.println("服务器:读取数据");
StringBuffer data = new StringBuffer(); //存储本次连接接收的数据
String info;
while((info = reader.readLine()) != null && !(info.equals("EOF"))){
data.append(info);
data.append("\n");
} 3. 如何关闭serversocket
因为serversocket的accept()方法是阻塞的,所以即使使用标志位通过while判断结束也不行。所以使用ServerSocket 的setSoTimeout() 方法,为ServerSocket的accept指定时长:
while(!isShutDown){ //持续监听客户端的连接请求 try { System.out.println("in listen"); serverSocket.setSoTimeout(2000); Socket socket = serverSocket.accept(); System.out.println("服务器端,socket 新连接"); new ServerSend(socket,socketpool,serverUI).start();//启动服务器端通信处理线程 } catch (IOException e1) { // e1.printStackTrace(); } }
不过上面的方法会抛出IO异常,需要捕获该异常,不过不影响使用。
4. 界面的动态加载
实现界面的动态加载,如果是增加控件,我是先将jpanel 中的控件先保存到一个ArrayList中,之后将面板清空,最后加上之前保存的控件以及新加入的控件。在之前的操作完成后,使用invalidate(),validate(),repaint() 方法更新,最后使用的那三个用来更新界面的是参考了网上的一个方法。
下面是部分代码实现:
ArrayList<JCheckBox> checkBoxs = new ArrayList<JCheckBox>();
JLabel tipLable = new JLabel(); //用户面板的提示文字标签
int componentcount = clientUI.getPanelUsers().getComponentCount();
for(int i=0;i<componentcount;++i){
Object obj = clientUI.getPanelUsers().getComponent(i);
if(obj instanceof JCheckBox){
checkBoxs.add((JCheckBox)obj);
}else if(obj instanceof
4000
JLabel){
tipLable = (JLabel)obj;
}
}
clientUI.getPanelUsers().removeAll(); //清除
clientUI.getPanelUsers().add(tipLable); //先增加提示文字标签
for(int i=0;i<checkBoxs.size();++i){
clientUI.getPanelUsers().add(checkBoxs.get(i));
}
System.out.println("客户端:新增用户 " + receivedData);
//在客户端界面上显示新用户进入的消息
//TODO
clientUI.getTextArea().setFont(new Font("Arial",Font.ITALIC,10));
clientUI.getTextArea().append("New User: " + receivedData + "Coming in\n");
clientUI.getTextArea().setFont(new Font("楷体",Font.PLAIN,20));
// clientUI.getTextArea().setFont(new Font());
JCheckBox jcheckBox = new JCheckBox(receivedData,false);
jcheckBox.setSize(80, 80);
clientUI.getPanelUsers().add(jcheckBox);
clientUI.getPanelUsers().invalidate();
clientUI.getPanelUsers().validate();
clientUI.getPanelUsers().repaint(); 如果是删除某个控件的话,可以简单一些,直接根据条件判断需要删除哪些,之后直接使用jpanel 的remove()方法,最后使用那三个方法更新。不知道需不需要考虑删除后控件的位置问题,我使用的布局是BoxLayout,Y轴布局,没有发现问题。
参考:
解决java获取panel中所有控件的问题 - CSDN博客: http://blog.csdn.net/u012505618/article/details/50149097
怎样在JPanel中添加删除组件????????-CSDN论坛: http://bbs.csdn.net/topics/60450227
如何关闭一个正在accept的ServerSocket? - CSDN博客: http://blog.csdn.net/qiuhan/article/details/6085176
相关文章推荐
- Java中使用Socket完成简单的远程计算(含粗糙界面和正则表达式判断数字类型)
- JAVAWEB开发之Servlet3.0新特性的使用以及注解的详细使用和自定义注解的方法、动态代理的使用、利用动态代理实现细粒度的权限控制以及类加载和泛型反射
- java动态数组、集合类、以及数组辅助工具的简单使用
- asp.net(c#)中使用反射动态加载dll简单示例
- JAVA类的静态加载和动态加载以及NoClassDefFoundError和ClassNotFoundException
- java使用socket实现http简单get请求
- 使用Java动态代理实现简单AOP
- DropDownList的动态加载,detailview使用以及FileUpload的上传
- android学习笔记---53_采用网页设计软件界面,以及使用android系统内置的浏览器,利用js调用java方法
- 某APK中使用了动态注册BroadcastReceiver,Launcher中动态加载此APK出现java.lang.SecurityException异常的解决方法
- android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- java swing jtree简单界面使用
- 简单得创建JAVASCRIPTE WEB丰富界面以及与JAVA服务互相访问
- 【Android开发学习44】android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- java hashMap 简单使用以及深度分析
- 使用 jquery 的 上传文件插件 uploadify 3.1 配合 java 来做一个简单的文件上次功能。并且在界面上有radio 的选择内容也要上传
- XNA Game Studio是一套有着强大功能和简单界面的游戏制作平台,游戏开发商和游戏玩家都可以使用这套工具开发针对Windows XP以及Xbox360的游戏,XNA Game Studio分为两种版本,一种是面向初学者的EXPRESS版本,还有一种
- android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- jsp/servlet使用ajax动态加载dtree, dtree样式/图片修改 (java 生成dtree servlet json)