用Socket 和Thread写一个简单的聊天功能,要求每一句代码都有注释。
C/S结构。要求很简单,把客户端的信息发送到服务端,然后服务端收到信息后显示,并转发给其他客户端
C/S结构。要求很简单,把客户端的信息发送到服务端,然后服务端收到信息后显示,并转发给其他客户端
解决方案 »
- 跪求!!谁有Java采集、传输和播放多媒体数据的好的解决方案。
- 希望大家能够给几题适合刚刚入一点点门的新手做的题目。谢谢了
- 怎样用应用程序来回复http请求
- 哪位弟兄的机器上装了JDK6.0的帮忙做个测试
- 一个jtable中可不可以显示二张表里的内容啊???------急
- 急觅O'Reilly的《Java RMI》!
- 创建File对象问题
- 对象传输问题!
- 从网上找到“利用Oracle自带的连接池类的一例”,这个和用datasource(JNDI)建立起来的有区别吗
- 请提供microsoft transction server和Borland AppServer的下载地址,谢谢
- 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("线程出错");
}
} }
}
注:代码不完整··不过可以让你看懂基本原理了··你再改一点就好··楼主好运··
在百度上找的话比在这个上面快很多的