socket网络编程--简单的多人聊天

来源:互联网 发布:阮佳网络班 编辑:程序博客网 时间:2024/05/16 20:30
//本代码参考于马士兵的代码,做了一些简单的改动,例如获取主机名称好让用户知道那句话是谁发的,Swing方面基本上全改了,关键地方加了我所理解的注释,关键线程方面的代码基本上用马老师的

//服务器端代码import java.awt.FlowLayout;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;import javax.swing.JFrame;import javax.swing.JScrollPane;import javax.swing.JTextArea;public class QLServer extends JFrame{public JTextArea jtextarea = null;public void lanuchFrame(String str){this.setName(str);init();}private void init() {setLayout(new FlowLayout());jtextarea =new JTextArea(20, 17);jtextarea.setLineWrap(true);jtextarea.setEditable(false);this.getContentPane().add(new JScrollPane(jtextarea));setVisible(true);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setSize(200,400);setLocationRelativeTo(null);setResizable(false);}ServerSocket server = null;Collection cClients = new ArrayList<ClientConn>();//加个泛型public void startServer() throws IOException{while(true){Socket s = server.accept();cClients.add(new ClientConn(s));jtextarea.append("new client login" + s.getInetAddress() + ":" + s.getPort()+"\n");}}public QLServer(int port,String str) throws IOException{server = new ServerSocket(port);lanuchFrame(str);}class ClientConn implements Runnable{Socket s = null;public ClientConn(Socket s){this.s = s;(new Thread(this)).start();}public void send(String str) throws IOException{DataOutputStream dos = new DataOutputStream(s.getOutputStream());dos.writeUTF(str);}public void dispose()//客户端下线{try {if (s != null) s.close();cClients.remove(this);jtextarea.append("A client out! \n");jtextarea.append("client count: " + cClients.size() + "\n\n");}catch (Exception e){e.printStackTrace();}}public void run(){try {DataInputStream dis = new DataInputStream(s.getInputStream());String str = dis.readUTF();while(str != null && str.length() !=0){System.out.println(str);for(Iterator it = cClients.iterator(); it.hasNext(); ){ClientConn cc = (ClientConn)it.next();if(this != cc){cc.send(str+" "+s.getInetAddress().getHostName());}}str = dis.readUTF();//少了这句话会无限输出//send(str);}this.dispose();} catch (Exception e) {this.dispose();}}}public static void main(String[] args) {try {QLServer qlserver = new QLServer(8888,"QLServer");qlserver.startServer();} catch (IOException e) {e.printStackTrace();}}}
===============================

import java.awt.FlowLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.BufferedReader;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.net.InetAddress;import java.net.Socket;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JScrollPane;import javax.swing.JTextArea;//客户端代码public class QLClient extends JFrame implements ActionListener{public JTextArea jtextarea1 = null;public JTextArea jtextarea2 = null;public JButton button = null;Socket s =null;public void launchFrame(String str){this.setName(str);init();}public QLClient(String str) throws IOException{launchFrame(str);s = new Socket("127.0.0.1",8888);//哪台电脑做服务器,IP地址改成那台机子的IP(new Thread(new ServeConn())).start();}private void init() {setLayout(new FlowLayout());jtextarea1 =new JTextArea(17, 16);jtextarea2 =new JTextArea(4, 16);jtextarea1.setLineWrap(true);jtextarea1.setEditable(false);jtextarea2.setLineWrap(true);button = new JButton("发送");button.addActionListener(this);//绑定button事件this.getContentPane().add(new JScrollPane(jtextarea1));this.getContentPane().add(new JScrollPane(jtextarea2));add(button);setVisible(true);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setSize(200,470);setLocationRelativeTo(null);setResizable(false);}public void send(String str) throws IOException{DataOutputStream dos = new DataOutputStream(s.getOutputStream());dos.writeUTF(str);}public void actionPerformed(ActionEvent e) {if(e.getSource()==button){String sendStr = jtextarea2.getText();if(sendStr.trim().length()==0){return;}try {this.send(sendStr);jtextarea2.setText("");InetAddress a;a = InetAddress.getLocalHost();String hostname = a.getHostName();jtextarea1.append(sendStr+"("+hostname+")"+"\n");} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}class ServeConn implements Runnable{public void run() {if(s == null) return;try {DataInputStream dis = new DataInputStream(s.getInputStream());String str = dis.readUTF();while (str != null && str.length() != 0){//System.out.println(str);QLClient.this.jtextarea1.append(str + "\n");//内部类用外类中的变量或方法加外类名str = dis.readUTF();}} catch (Exception e){e.printStackTrace();}}}//main主函数入口public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));QLClient qlclient = new QLClient("QLClient");String str = br.readLine();while(str!=null&&str.length()!=0){qlclient.send(str);str = br.readLine();//防止死循环}qlclient.s.close();}}

以上代码供参考,关于异常基本上没有处理,所以操作顺序不对可能会出现异常。