java实现简单聊天程序(集合,线程,I/O,网络编程)
2017-06-20 22:35
627 查看
这半个月的大作业,程序有一些不完善的地方有待提高,但是基本的聊天室功能已经可以实现
还没有接触javaFx所以用了swing做了简陋的界面
补充:{
今天突然记起来,把这个大作业交了,然后大佬突然问我这个程序有没有线程安全问题,怎么处理的。
我以为这只是把socket传入的字节重新传到客户端不存在修改也不存在线程的安全问题,大佬说只要有多个线程共享的数据,就有可能有线程安全问题!!!切记
我恰好在服务器端用了vector集合存储了线程,所以避免了安全性问题,但是如果用了其他的容器还是会出现线程安全问题。
例如,ArrayList里,容量是有一个上限的,在当前容量已满的情况下,会进行扩容,先判断是否达到容量上限,如果没有,就将进行扩容,如果达到则会报异常。
如果没有给线程上锁,当有两个对象同时加入ArrayList里且容量只够再一次扩容时,会爆内存。
而使用vector则没有这种担忧,看过vector源码的API就会知道,vector的实现方法都用synchronized包装了。
synchronized:
这是java语言的关键字,被它修饰的方法或代码块在执行的时候能够保证在同一时刻最多只有一个线程执行该段代码,相当于一个上锁的操作。
}
截图:
客户端:
服务器端
还没有接触javaFx所以用了swing做了简陋的界面
补充:{
今天突然记起来,把这个大作业交了,然后大佬突然问我这个程序有没有线程安全问题,怎么处理的。
我以为这只是把socket传入的字节重新传到客户端不存在修改也不存在线程的安全问题,大佬说只要有多个线程共享的数据,就有可能有线程安全问题!!!切记
我恰好在服务器端用了vector集合存储了线程,所以避免了安全性问题,但是如果用了其他的容器还是会出现线程安全问题。
例如,ArrayList里,容量是有一个上限的,在当前容量已满的情况下,会进行扩容,先判断是否达到容量上限,如果没有,就将进行扩容,如果达到则会报异常。
如果没有给线程上锁,当有两个对象同时加入ArrayList里且容量只够再一次扩容时,会爆内存。
而使用vector则没有这种担忧,看过vector源码的API就会知道,vector的实现方法都用synchronized包装了。
synchronized:
这是java语言的关键字,被它修饰的方法或代码块在执行的时候能够保证在同一时刻最多只有一个线程执行该段代码,相当于一个上锁的操作。
}
截图:
客户端:
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; public class Client extends JFrame { private static final long serialVersionUID = 1L; JTextField JTF = new JTextField(); JTextArea JTA = new JTextArea(); JScrollPane JSP = new JScr 4000 ollPane(JTA); Socket socket = null; OutputStream ops = null; InputStream ips = null; String name = new String(); public void makeWindow(){ name = JOptionPane.showInputDialog(null, "请输入用户名字", "输入用户名", JOptionPane.INFORMATION_MESSAGE); connect(); JFrame frame = new JFrame("聊天窗口"); frame.setSize(500, 400); Container contentPane = frame.getContentPane(); JPanel panel = new JPanel(); panel.setBackground(Color.CYAN); JButton bts = new JButton("send"); JButton btc = new JButton("close"); panel.add(bts); panel.add(btc); JTA.setEditable(false); JPanel panel_ = new JPanel(new BorderLayout()); panel_.add(JTF, BorderLayout.SOUTH); // panel_.add(JTA, BorderLayout.CENTER); panel_.add(JSP, BorderLayout.CENTER); contentPane.add(panel, BorderLayout.SOUTH); contentPane.add(panel_, BorderLayout.CENTER); frame.setVisible(true); frame.setLocationRelativeTo(null); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { CloseAll(); System.out.println("已关闭窗口"); System.exit(0); } }); btc.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { CloseAll(); System.out.println("press the btc"); System.exit(0); } }); bts.addActionListener(new ButtonListener()); new Thread(new ClientTest()).start(); } public class ButtonListener implements ActionListener{ public void actionPerformed(ActionEvent arg0) { String str = new String(); str = JTF.getText(); Date date = new Date(); DateFormat format = new SimpleDateFormat("HH:mm:ss"); String time = format.format(date); str = name + " send at " + time + ":\n" + str; JTF.setText(""); try { ops.write(str.getBytes()); } catch (IOException e) { e.printStackTrace(); CloseAll(); } } } public static void main(String[] args) { Client c = new Client(); c.makeWindow(); } public void connect(){ try { socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090); ops = socket.getOutputStream(); System.out.println("Open the Socket"); } catch (UnknownHostException e) { CloseAll(); e.printStackTrace(); } catch (IOException e) { CloseAll(); e.printStackTrace(); } } public void CloseAll(){ if(ips != null){ try { ips.close(); } catch (IOException e) { e.printStackTrace(); } } if(ops != null){ try { ops.close(); } catch (IOException e) { e.printStackTrace(); } } if(socket != null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } System.out.println("Close All"); } class ClientTest implements Runnable{ @Override public void run(){ try { ips = socket.getInputStream(); byte[] b = new byte[1024]; int len; while((len = ips.read(b)) != -1){ String receStr = new String(b, 0, len); String appear = new String(); appear = JTA.getText()+ receStr + '\n'; JTA.setText(appear); JTF.setText(""); } } catch (IOException e) { System.out.println("I hava closed! Please don't send message!"); } } } }
服务器端
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.Vector; public class Server { public Vector<ServerTest> v = new Vector<ServerTest>(); ServerSocket ss = null; // Socket s = null; // InputStream ips = null; // OutputStream ops = null; public void receive(){ try { ss = new ServerSocket(9090); System.out.println("I am the Server"); } catch (IOException e1) { e1.printStackTrace(); } try { while(true){ Socket s = ss.accept(); ServerTest st = new ServerTest(s); System.out.println("a client connected!"); v.add(st); new Thread(st).start(); } } catch (IOException e) { e.printStackTrace(); }finally{ if(ss != null){ try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } System.out.println("I have close all!"); } } public static void main(String[] args) { Server server = new Server(); server.receive(); } class ServerTest implements Runnable{ Socket s = null; InputStream ips = null; OutputStream ops = null; public ServerTest(Socket s){ this.s = s; } public void run() { try { while(true) { this.ips = this.s.getInputStream(); this.ops = this.s.getOutputStream(); byte[] b = new byte[1024]; int len; while((len = this.ips.read(b)) != -1){ String str = new String(b, 0, len); for(int i = 0; i < v.size(); i++){ ServerTest st = v.get(i); st.ops.write(str.getBytes()); } } } } catch (IOException e) { e.printStackTrace(); }finally{ if(ips != null){ try { ips.close(); } catch (IOException e) { e.printStackTrace(); } } if(ops != null){ try { ops.close(); } catch (IOException e) { e.printStackTrace(); } } if(s != null){ try { s.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }
相关文章推荐
- java实现简单聊天程序(集合,线程,I/O,网络编程)
- java实现简单聊天程序(集合,线程,I/O,网络编程)
- java用ServerSocket类结合io流实现一对一聊天(java实现简单的TCP聊天程序只能用telnet连接后方可使用)
- 一个Java实现的简单的多个客户端聊天程序(未测试)
- JAVA系列课程讲座二:使用Socket通信实现简单聊天通信程序(UDP方式)
- Java_GUI创建单机版QQ聊天小程序并实现简单的小功能(附所有源码)
- java-用java.net.Socket和java.net.ServerSocket实现简单的聊天程序
- java实现简单TCP聊天程序
- 黑马程序员-JAVA学习之用多线程实现简单UDP聊天程序
- JAVA网络编程——简单的聊天程序
- java swing实现简单的socket通讯聊天程序源码
- 【java学习记录】12.用Socket网络访问方法,实现简单的网络聊天程序
- java中集合的运用,实现一个简单的购物程序
- java用socket和serversocket实现一对一聊天(java实现简单的TCP聊天程序)
- [Java] Socket/ServerSocket 控制台简单聊天程序
- 利用java实现一个简单的远程监控程序
- 用java实现的一个简单web服务器程序
- 初识委托和线程并实现一个简单摇奖程序
- Socket通讯编程实现简单的任意聊天程序
- Java实现控制线程超时的简单方法