精华帖 (0) :: 良好帖 (0) :: 新手帖 (14) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-02-17
package test; import java.io.*; import java.net.*; public class MultiServer { public MultiServer() throws IOException { ServerSocket ss=new ServerSocket(7777); while(true){ Socket socket=ss.accept(); new DealMessage(socket).start(); } } public static void main(String[] args) { try { new MultiServer(); } catch (IOException e) { e.printStackTrace(); } } } class DealMessage extends Thread { private Socket socket; private InputStream in; private OutputStream out; public DealMessage(Socket s) throws IOException { this.socket = s; this.in = socket.getInputStream(); this.out = socket.getOutputStream(); } public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(in)); System.out.println("you IP is: " + socket.getInetAddress()+":"+socket.getPort()); System.out.println("you enter is: " + br.readLine()); } catch (IOException e) { e.printStackTrace(); } } public void finalize() throws IOException { if (in != null) { in.close(); } if (out != null) { out.close(); } } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-05-11
我在服务器端维护了一个客户端请求的list
当客户端退出时,服务器端将这个请求的客户端删除 在这里遇到了些问题 主要不知道怎么讲list中下线的客户端删除 import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ChatServer { List<Client> clients = new ArrayList<Client>(); public static void main(String[] args) { new ChatServer().start(); } public void start() { boolean started = false; ServerSocket ss = null; try { ss = new ServerSocket(8888); started = true; } catch (BindException e) { System.out.println("端口正在被使用,请关闭相应程序!"); System.exit(0); } catch (IOException e) { e.printStackTrace(); } try { while (started) { Socket s = ss.accept(); Client c = new Client(s); clients.add(c); System.out.println("a client connected!"); new Thread(c).start(); } } catch (IOException e) { e.printStackTrace(); } finally { try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 每个请求过来启用一个线程来处理<br> */ private class Client implements Runnable { Socket socket = null; DataInputStream dis = null; DataOutputStream dos = null; boolean connected = false; Client(Socket s) { try { this.socket = s; dis = new DataInputStream(s.getInputStream()); dos = new DataOutputStream(s.getOutputStream()); connected = true; } catch (IOException e) { e.printStackTrace(); } } public void run() { while (connected) { try { Iterator<Client> it = clients.iterator(); String msg = dis.readUTF(); while (it.hasNext()) { Client c = it.next(); c.send(msg); } } catch (EOFException eof) { connected = false; // 需要在序列中将退出的client去除, // 迭代过程中 // 不能使用Collection本身的remove方法, // 会抛出java.util.ConcurrentModificationException // 使用iterator的remove方法 } catch (IOException e) { e.printStackTrace(); } } } private void send(String str) throws IOException { dos.writeUTF(str); } } } public class ChatClient extends Frame { private static final long serialVersionUID = 5798410085795768914L; public TextField tf = new TextField(); public TextArea ta = new TextArea(); DataOutputStream dos = null; DataInputStream dis = null; public Socket socket = null; boolean connected = false; Thread receiver = new Thread(new ReceiverThread()); public static void main(String[] args) { new ChatClient().launchFrame(); } public void launchFrame() { this.setLocation(250, 100); this.setSize(500, 600); this.add(tf, BorderLayout.SOUTH); this.add(ta, BorderLayout.NORTH); this.pack(); this.addWindowListener(new WindowMonitor()); tf.addKeyListener(new KeyMonitor()); connect(); receiver.start(); this.setVisible(true); } public void connect() { try { socket = new Socket("127.0.0.1", 8888); dos = new DataOutputStream(socket.getOutputStream()); dis = new DataInputStream(socket.getInputStream()); connected = true; } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void disconnect() { try { dos.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } private class WindowMonitor extends WindowAdapter { @Override public void windowClosing(WindowEvent e) { disconnect(); System.exit(0); } } private class KeyMonitor extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); if (KeyEvent.VK_ENTER == keyCode) { try { dos.writeUTF(tf.getText().trim()); dos.flush(); } catch (IOException ioe) { ioe.printStackTrace(); } tf.setText(""); } } } private class ReceiverThread implements Runnable { public void run() { try { while (connected) { String str = dis.readUTF(); ta.setText(ta.getText() + str + '\n'); } } catch (SocketException e) { System.out.println("客户端断开连接!"); connected = false; } catch (EOFException e) { System.out.println("客户端断开连接!"); } catch (IOException e) { e.printStackTrace(); } } } } |
|
返回顶楼 | |
发表时间:2009-05-11
lucane 写道 我在服务器端维护了一个客户端请求的list
当客户端退出时,服务器端将这个请求的客户端删除 在这里遇到了些问题 主要不知道怎么讲list中下线的客户端删除 import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ChatServer { List<Client> clients = new ArrayList<Client>(); public static void main(String[] args) { new ChatServer().start(); } public void start() { boolean started = false; ServerSocket ss = null; try { ss = new ServerSocket(8888); started = true; } catch (BindException e) { System.out.println("端口正在被使用,请关闭相应程序!"); System.exit(0); } catch (IOException e) { e.printStackTrace(); } try { while (started) { Socket s = ss.accept(); Client c = new Client(s); clients.add(c); System.out.println("a client connected!"); new Thread(c).start(); } } catch (IOException e) { e.printStackTrace(); } finally { try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 每个请求过来启用一个线程来处理<br> */ private class Client implements Runnable { Socket socket = null; DataInputStream dis = null; DataOutputStream dos = null; boolean connected = false; Client(Socket s) { try { this.socket = s; dis = new DataInputStream(s.getInputStream()); dos = new DataOutputStream(s.getOutputStream()); connected = true; } catch (IOException e) { e.printStackTrace(); } } public void run() { while (connected) { try { Iterator<Client> it = clients.iterator(); String msg = dis.readUTF(); while (it.hasNext()) { Client c = it.next(); c.send(msg); } } catch (EOFException eof) { connected = false; // 需要在序列中将退出的client去除, // 迭代过程中 // 不能使用Collection本身的remove方法, // 会抛出java.util.ConcurrentModificationException // 使用iterator的remove方法 } catch (IOException e) { e.printStackTrace(); } } } private void send(String str) throws IOException { dos.writeUTF(str); } } } public class ChatClient extends Frame { private static final long serialVersionUID = 5798410085795768914L; public TextField tf = new TextField(); public TextArea ta = new TextArea(); DataOutputStream dos = null; DataInputStream dis = null; public Socket socket = null; boolean connected = false; Thread receiver = new Thread(new ReceiverThread()); public static void main(String[] args) { new ChatClient().launchFrame(); } public void launchFrame() { this.setLocation(250, 100); this.setSize(500, 600); this.add(tf, BorderLayout.SOUTH); this.add(ta, BorderLayout.NORTH); this.pack(); this.addWindowListener(new WindowMonitor()); tf.addKeyListener(new KeyMonitor()); connect(); receiver.start(); this.setVisible(true); } public void connect() { try { socket = new Socket("127.0.0.1", 8888); dos = new DataOutputStream(socket.getOutputStream()); dis = new DataInputStream(socket.getInputStream()); connected = true; } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void disconnect() { try { dos.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } private class WindowMonitor extends WindowAdapter { @Override public void windowClosing(WindowEvent e) { disconnect(); System.exit(0); } } private class KeyMonitor extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); if (KeyEvent.VK_ENTER == keyCode) { try { dos.writeUTF(tf.getText().trim()); dos.flush(); } catch (IOException ioe) { ioe.printStackTrace(); } tf.setText(""); } } } private class ReceiverThread implements Runnable { public void run() { try { while (connected) { String str = dis.readUTF(); ta.setText(ta.getText() + str + '\n'); } } catch (SocketException e) { System.out.println("客户端断开连接!"); connected = false; } catch (EOFException e) { System.out.println("客户端断开连接!"); } catch (IOException e) { e.printStackTrace(); } } } } 异常时候删除,list需要同步处理. |
|
返回顶楼 | |
发表时间:2009-05-11
最后修改:2009-05-11
san_yun 写道 异常时候删除,list需要同步处理.
你说的是对的 但程序还是会出点bug 我这个代码list中放的是Thread 我有点觉得这样写是错的 我看到有别人是把Socket放在list中的 这样有区别吗 |
|
返回顶楼 | |
发表时间:2009-05-12
lucane 写道 san_yun 写道异常时候删除,list需要同步处理. 你说的是对的 但程序还是会出点bug 我这个代码list中放的是Thread 我有点觉得这样写是错的 我看到有别人是把Socket放在list中的 这样有区别吗 保存Socket要更好一些,比如要关掉某一个Socket连接,或者身某个Socket写信息,如果你要是保存Thread,然后Thread里面包含Socket的话,你想用什么方式实现? |
|
返回顶楼 | |
发表时间:2009-05-12
现在不都用NIO吗?
|
|
返回顶楼 | |
发表时间:2009-05-12
vinter 写道 lucane 写道 san_yun 写道异常时候删除,list需要同步处理. 你说的是对的 但程序还是会出点bug 我这个代码list中放的是Thread 我有点觉得这样写是错的 我看到有别人是把Socket放在list中的 这样有区别吗 保存Socket要更好一些,比如要关掉某一个Socket连接,或者身某个Socket写信息,如果你要是保存Thread,然后Thread里面包含Socket的话,你想用什么方式实现? 我开始想的是从list中删除的话 socket这些资源应该会被回收 我也不是狠懂 正在找这方面的例子。。 |
|
返回顶楼 | |
发表时间:2009-05-12
保存在list中还是可以的,楼主是选择长连接?保存以后还要做什么特殊处理?
会群发消息? 另外list需要做同步处理。 |
|
返回顶楼 | |
发表时间:2009-05-13
cjmcn-sh 写道 保存在list中还是可以的,楼主是选择长连接?保存以后还要做什么特殊处理?
会群发消息? 另外list需要做同步处理。 应该算是长连接 想让用户退出的时候断开链接 给在线所有用户发消息 |
|
返回顶楼 | |
发表时间:2009-05-14
搞点代码示意一下:
private static final Set UserSet= Collections .synchronizedSet(new HashSet()); 然后分几种状态: OnAccept: UserSet.add(Socket); OnClose; UserSet.remove(Socket); OnSend: synchronized (UserSet){ 按照UserSet中socket发送 } OnException: UserSet.remove(Socket); |
|
返回顶楼 | |