本人刚刚学,求一个例子! 用Socket 和Thread写一个简单的聊天功能,要求每一句代码都有注释。C/S结构。要求很简单,把客户端的信息发送到服务端,然后服务端收到信息后显示,并转发给其他客户端 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 网上有很多Socket聊天的程序,可以自己找,看不懂的地方,就查下资料,还不理解的话就问,每一句都有注释的话也不利于学习,况且谁也不可能给你这样的代码 每一句都要注释...网上这么多代码.哪句看不懂再百度或GOOGLE可能对你帮助更大 顶到明年都恐怕没人帮你每句都加注释的下个java 网络编程的教程看看再说吧http://www.verycd.com/search/folders/java+%E7%BD%91%E7%BB%9C 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("线程出错"); } } }}注:代码不完整··不过可以让你看懂基本原理了··你再改一点就好··楼主好运·· Socket聊天在百度上找的话比在这个上面快很多的 -classpath这个参数怎么用啊 求解一个正则表达式 Java和access数据库的问题,高手帮忙 进制转换 java的疑难问题,高手请进 求一超难算法,高手请进!!! 一个简单的问题! 欢迎大家的参与!!!!你一定会受益非线的 推荐一本swing的书吧 怎样修改?????????? java中怎么去除数值.0后缀? 模拟QQ 在数据库里怎样设计好友列表
http://www.verycd.com/search/folders/java+%E7%BD%91%E7%BB%9C
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("线程出错");
}
} }
}
注:代码不完整··不过可以让你看懂基本原理了··你再改一点就好··楼主好运··
在百度上找的话比在这个上面快很多的