用Socket 和Thread写一个简单的聊天功能,要求每一句代码都有注释。
C/S结构。要求很简单,把客户端的信息发送到服务端,然后服务端收到信息后显示,并转发给其他客户端

解决方案 »

  1.   

    网上有很多Socket聊天的程序,可以自己找,看不懂的地方,就查下资料,还不理解的话就问,每一句都有注释的话也不利于学习,况且谁也不可能给你这样的代码
      

  2.   

    每一句都要注释...网上这么多代码.哪句看不懂再百度或GOOGLE可能对你帮助更大
      

  3.   

    顶到明年都恐怕没人帮你每句都加注释的下个java 网络编程的教程看看再说吧
    http://www.verycd.com/search/folders/java+%E7%BD%91%E7%BB%9C
      

  4.   

    server端:package com.cme.first;import java.io.*;
    import java.net.*;
    import java.util.*;/*
     * 服务器的类
     */public class ChatServer {
    boolean started;
    static ServerSocket ss = null;
    static DataInputStream dis = null;
    List<Client> clients = new ArrayList<Client>(); public static void main(String[] args) {
    new ChatServer().start();
    } // 自定义方法··用于新建一个服务器·
    public void start() {
    try {
    ss = new ServerSocket(3323);// 定义一个服务器端的类的实例·传8888端口
    started = true;
    } catch (Exception e) {
    System.out.println("端口使用中·秦关闭程序");// 避免服务器被启动两次
    System.exit(0);
    }
    try {
    while (started) {
    // 将服务器端监听到的客户端赋予s
    Socket s = ss.accept();
    Client c = new Client(s);// 每当有一个客户端连接上来的时候就创建一个线程
    new Thread(c).start();// 启动线程
    clients.add(c);
    }
    } catch (IOException e) {
    e.printStackTrace();
    } finally {// 无论是否捕获到一场都执行以下语句
    try {
    dis.close();// 关闭掉流与服务器
    ss.close();
    } catch (Exception e) {
    e.printStackTrace();
    } }
    } // 定义一个线程类,内部类
    class Client implements Runnable {
    // 线程类的各个成员变量
    private Socket s;
    private DataInputStream dis = null;
    private DataOutputStream dos = null;
    private boolean b2 = true; // 自定义一个方法··用于将客户端的内容发送
    public void send(String string) {
    try {
    dos.writeUTF(string);
    } catch (IOException e1) {
    e1.printStackTrace();
    }
    } // 线程类的构造方法,内传一个客户端的实例
    Client(Socket s) {
    this.s = s;
    try {
    dis = new DataInputStream(s.getInputStream());
    } catch (IOException e) {
    e.printStackTrace();
    }
    } // 线程启动所执行的方法
    public void run() {
    System.out.println("一个客户端进来");
    // 再一次一个死循环·用于每次客户端发送字符串都能重新读入
    try {
    while (b2) {
    String str; str = dis.readUTF();// 读取到流的东西并打印出
    System.out.println(str);
    // 使用一个循环·将接受到的客户端发来的字符串发出
    for (int i = 0; i < clients.size(); i++) {
    Client c = clients.get(i);
    c.send(str);
    System.out.println("已发送");
    }
    }
    } catch (Exception e) {
    e.getStackTrace();
    } finally {
    try {
    if(dis != null) dis.close();
    if(dos != null) dos.close();
    if(s != null)  {
    s.close();
    //s = null;
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    client端:package com.cme.first;import java.awt.*;
    import java.awt.event.*;
    import java.io.*;import java.net.*;public class ChatClient extends Frame {

    private static final long serialVersionUID = 1L;
    DataOutputStream dos = null;
    DataInputStream dis = null;
    Socket s = null;
    TextField tfText = new TextField();// 文本框
    TextArea taContent = new TextArea();// 定义一个用于存储聊天内容的控件,可以存多行
    private boolean bConnected = false;
    Thread tRead = new Thread(new RecvThread()); public static void main(String[] args) {
    new ChatClient().launchFrame();
    } public void launchFrame() {
    this.setBounds(200, 100, 500, 400);
    this.add(taContent, BorderLayout.NORTH);
    this.add(tfText, BorderLayout.SOUTH);
    tfText.addActionListener(new TFListener());// 添加文本框的监听器··用于将输入内容存
    // 在特定的框内荣,并且是回车提交
    // 给窗体添加一个监听器··里面包含着窗体的关闭事件,并且将流与客户端端口关掉。匿名类
    this.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    setVisible(false);
    try {
    dos.close();
    s.close();
    } catch (IOException e1) {
    e1.printStackTrace();
    }// 关掉流和当前页面
    System.exit(0);
    }
    });
    pack();
    this.setVisible(true);
    connet();// 当窗体出来后就直接连接到服务器
    tRead.start();// 连接上服务器之后启动线程
    } public void connet() {
    /*
     * 自定义方法·写出客户端
     */
    try {
    s = new Socket("127.0.0.1", 3323);// 一个新的客户端连接到本机服务器的8888端口
    System.out.println("链接成功!");// 测试语句·写于最左边
    // 链接成功后创建流对象,并且修改用于控制线程类的变量bConnected的值为true
    dos = new DataOutputStream(s.getOutputStream());
    dis = new DataInputStream(s.getInputStream());
    bConnected = true;
    // 捕获一下两种异常
    } catch (UnknownHostException e) {
    System.out.print("服务器没有打开");
    // e.printStackTrace();
    } catch (IOException e) {
    System.out.print("服务器没有打开");
    // e.printStackTrace();
    }
    } // tfText文本框的监听器
    private class TFListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    String str = tfText.getText() + "\n";
    taContent.setText(str);// 将输入框内的内容放在存储框里
    tfText.setText(""); // 将客户端输入的一行字发送到服务器
    try {
    // 将字符串写出
    dos.writeUTF(str);
    dos.flush();// 刷新
    // 捕获任何异常·并且打印出服务器端的错误
    } catch (Exception e1) {
    // e1.printStackTrace();
    System.out.println("服务器端被关闭了·发送失败");
    }
    }
    } // 线程类·用于接收服务器的发送的内容
    private class RecvThread implements Runnable { public void run() {
    try {
    while (bConnected) {
    String str = dis.readUTF();
    System.out.println(str);
    taContent.setText(taContent.getText() + str + '\n');
    taContent.setText(str);
    }
    } catch (Exception e) {
    e.printStackTrace();
    System.out.println("线程出错");
    }
    } }
    }
    注:代码不完整··不过可以让你看懂基本原理了··你再改一点就好··楼主好运··
      

  5.   

    Socket聊天
    在百度上找的话比在这个上面快很多的