import java.net.*
import java.awt.*
import javax.swing.*
import java.awt.event.*//引入包。
public class ChatClient {
public static void main(String[] args) {
ChatClient cc = new ChatClient()
cc.receive()
}
JTextField jtf// 文本条
JTextArea jta//文本域。
Socket s//客户端
PrintWriter out//输出流
BufferedReader in//输入流
public ChatClient() {
JFrame frame = new JFrame("ChatClient")//窗口
frame.setSize(400, 300)//大小
jta = new JTextArea()//文本域
jta.setEditable(false)//不可编辑
jtf = new JTextField()//文件条
jtf.addActionListener(new ActionListener() { //添加监听。
public void actionPerformed(ActionEvent arg0) {
send()//调用send()方法
}
})
frame.getContentPane().add(new JScrollPane(jta))//添加滚动条
frame.getContentPane().add(jtf, "South")//添加文本条
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)//关闭窗口。
frame.setVisible(true)//可显示的。
try {
s = new Socket("127.0.0.1", 9000)//连接服务端 socket("主机名",端口号)
in = new BufferedReader(new InputStreamReader(s.getInputStream()))//建立输入流
out = new PrintWriter(s.getOutputStream())//输出流
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace()
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace()
}
}
public void receive() { //接受服务端发来别的客户端的信息。
while (true) {
try {
String text = in.readLine()//读一行
this.jta.append(text + "\n")//jta 添加上读入的。
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace()
return
}
}
}
public void send() { //发送消息
String text = this.jtf.getText()//得到你输入的消息
this.jtf.setText("")//在文本域中显示你输入的消息。
out.println(text)//打印出。
out.flush()//清空
}
}
Server端
import java.net.*
import java.io.*
import java.util.*//引入包
public class ChatServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(9000)//建立服务端,端口号为9000
List list = new ArrayList()//创建个List集合。
while (true) {
Socket s = ss.accept()//等待客户端的请求。
list.add(s)//把每一个client都add到集合中去。
Thread t = new ServerThread(s, list)//线程。
t.start()//启动。
}
}
}
class ServerThread extends Thread {
Socket s
List list
BufferedReader in
PrintWriter out
public ServerThread(Socket s, List list) { //构造。传入socket和list。
this.s = s
this.list = list
try {
in = new BufferedReader(new InputStreamReader(s.getInputStream()))//输入流
out = new PrintWriter(s.getOutputStream())//输出流
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace()
}
}
public void run() { //必须实现其run()方法。
while (true) {
try {
String str = in.readLine()//得到client端的message。
if (str == null) //如果没有消息就返回。
return
Iterator it = list.iterator()//遍历list。
while (it.hasNext()) { //如果list有下一个
Socket socket = (Socket) (it.next())//因为list中都是存的socket
PrintWriter o = new PrintWriter(socket.getOutputStream())//输出流
o.println(str)//输出
o.flush()//清空
}
} catch (IOException e) {
// TODO Auto-generated catch block
// e.printStackTrace()
return
}
}
}
}
共四个java文件,源代码如下:import java.awt.*
import java.net.*
import java.awt.event.*
import java.io.*
import java.util.Hashtable
public class ChatArea extends Panel implements ActionListener,Runnable
{
Socket socket=null
DataInputStream in=null
DataOutputStream out=null
Thread threadMessage=null
TextArea 谈话显示区,私聊显示区=null
TextField 送出信息=null
Button 确定,刷新谈话区,刷新私聊区
Label 提示条=null
String name=null
Hashtable listTable
List listComponent=null
Choice privateChatList
int width,height
public ChatArea(String name,Hashtable listTable,int width,int height)
{
setLayout(null)
setBackground(Color.orange)
this.width=width
this.height=height
setSize(width,height)
this.listTable=listTable
this.name=name
threadMessage=new Thread(this)
谈话显示区=new TextArea(10,10)
私聊显示区=new TextArea(10,10)
确定=new Button("送出信息到:")
刷新谈话区=new Button("刷新谈话区")
刷新私聊区=new Button("刷新私聊区")
提示条=new Label("双击聊天者可私聊",Label.CENTER)
送出信息=new TextField(28)
确定.addActionListener(this)
送出信息.addActionListener(this)
刷新谈话区.addActionListener(this)
刷新私聊区.addActionListener(this)
listComponent=new List()
listComponent.addActionListener(this)
privateChatList=new Choice()
privateChatList.add("大家(*)")
privateChatList.select(0)
add(谈话显示区)
谈话显示区.setBounds(10,10,(width-120)/2,(height-120))
add(私聊显示区)
私聊显示区.setBounds(10+(width-120)/2,10,(width-120)/2,(height-120))
add(listComponent)
listComponent.setBounds(10+(width-120),10,100,(height-160))
add(提示条)
提示条.setBounds(10+(width-120),10+(height-160),110,40)
Panel pSouth=new Panel()
pSouth.add(送出信息)
pSouth.add(确定)
pSouth.add(privateChatList)
pSouth.add(刷新谈话区)
pSouth.add(刷新私聊区)
add(pSouth)
pSouth.setBounds(10,20+(height-120),width-20,60)
}
public void setName(String s)
{
name=s
}
public void setSocketConnection(Socket socket,DataInputStream in,DataOutputStream out)
{
this.socket=socket
this.in=in
this.out=out
try
{
threadMessage.start()
}
catch(Exception e)
{
}
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==确定||e.getSource()==送出信息)
{
String message=""
String people=privateChatList.getSelectedItem()
people=people.substring(0,people.indexOf("("))
message=送出信息.getText()
if(message.length()>0)
{
try {
if(people.equals("大家"))
{
out.writeUTF("公共聊天内容:"+name+"说:"+message)
}
else
{
out.writeUTF("私人聊天内容:"+name+"悄悄地说:"+message+"#"+people)
}
}
catch(IOException event)
{
}
}
}
else if(e.getSource()==listComponent)
{
privateChatList.insert(listComponent.getSelectedItem(),0)
privateChatList.repaint()
}
else if(e.getSource()==刷新谈话区)
{
谈话显示区.setText(null)
}
else if(e.getSource()==刷新私聊区)
{
私聊显示区.setText(null)
}
}
public void run()
{
while(true)
{
String s=null
try
{
s=in.readUTF()
if(s.startsWith("聊天内容:"))
{
String content=s.substring(s.indexOf(":")+1)
谈话显示区.append("\n"+content)
}
if(s.startsWith("私人聊天内容:"))
{
String content=s.substring(s.indexOf(":")+1)
私聊显示区.append("\n"+content)
}
else if(s.startsWith("聊天者:"))
{
String people=s.substring(s.indexOf(":")+1,s.indexOf("性别"))
String sex=s.substring(s.indexOf("性别")+2)
listTable.put(people,people+"("+sex+")")
listComponent.add((String)listTable.get(people))
listComponent.repaint()
}
else if(s.startsWith("用户离线:"))
{
String awayPeopleName=s.substring(s.indexOf(":")+1)
listComponent.remove((String)listTable.get(awayPeopleName))
listComponent.repaint()
谈话显示区.append("\n"+(String)listTable.get(awayPeopleName)+"离线")
listTable.remove(awayPeopleName)
}
Thread.sleep(5)
}
catch(IOException e)
{
listComponent.removeAll()
listComponent.repaint()
listTable.clear()
谈话显示区.setText("和服务器的连接已中断\n必须刷新浏览器才能再次聊天")
break
}
catch(InterruptedException e)
{
}
}
}
}
ChatServer.java
import java.io.*
import java.net.*
import java.util.*
public class ChatServer
{
public static void main(String args[])
{
ServerSocket server=null
Socket you=null
Hashtable peopleList
peopleList=new Hashtable()
while(true)
{
try
{
server=new ServerSocket(6666)
}
catch(IOException e1)
{
System.out.println("正在监听")
}
try {
you=server.accept()
InetAddress address=you.getInetAddress()
System.out.println("用户的IP:"+address)
}
catch (IOException e)
{
}
if(you!=null)
{
Server_thread peopleThread=new Server_thread(you,peopleList)
peopleThread.start()
}
else {
continue
}
}
}
}
class Server_thread extends Thread
{
String name=null,sex=null
Socket socket=null
File file=null
DataOutputStream out=null
DataInputStream in=null
Hashtable peopleList=null
Server_thread(Socket t,Hashtable list)
{
peopleList=list
socket=t
try {
in=new DataInputStream(socket.getInputStream())
out=new DataOutputStream(socket.getOutputStream())
}
catch (IOException e)
{
}
}
public void run()
{
while(true)
{String s=null
try
{
s=in.readUTF()
if(s.startsWith("姓名:"))
{
name=s.substring(s.indexOf(":")+1,s.indexOf("性别"))
sex=s.substring(s.lastIndexOf(":")+1)
boolean boo=peopleList.containsKey(name)
if(boo==false)
{
peopleList.put(name,this)
out.writeUTF("可以聊天:")
Enumeration enum=peopleList.elements()
while(enum.hasMoreElements())
{
Server_thread th=(Server_thread)enum.nextElement()
th.out.writeUTF("聊天者:"+name+"性别"+sex)
if(th!=this)
{
out.writeUTF("聊天者:"+th.name+"性别"+th.sex)
}
}
}
else
{
out.writeUTF("不可以聊天:")
}
}
else if(s.startsWith("公共聊天内容:"))
{
String message=s.substring(s.indexOf(":")+1)
Enumeration enum=peopleList.elements()
while(enum.hasMoreElements())
{
((Server_thread)enum.nextElement()).out.writeUTF("聊天内容:"+message)
}
}
else if(s.startsWith("用户离开:"))
{
Enumeration enum=peopleList.elements()
while(enum.hasMoreElements())
{ try
{
Server_thread th=(Server_thread)enum.nextElement()
if(th!=this&&th.isAlive())
{
th.out.writeUTF("用户离线:"+name)
}
}
catch(IOException eee)
{
}
}
peopleList.remove(name)
socket.close()
System.out.println(name+"用户离开了")
break
}
else if(s.startsWith("私人聊天内容:"))
{
String 悄悄话=s.substring(s.indexOf(":")+1,s.indexOf("#"))
String toPeople=s.substring(s.indexOf("#")+1)
Server_thread toThread=(Server_thread)peopleList.get(toPeople)
if(toThread!=null)
{
toThread.out.writeUTF("私人聊天内容:"+悄悄话)
}
else
{
out.writeUTF("私人聊天内容:"+toPeople+"已经离线")
}
}
}
catch(IOException ee)
{
Enumeration enum=peopleList.elements()
while(enum.hasMoreElements())
{ try
{
Server_thread th=(Server_thread)enum.nextElement()
if(th!=this&&th.isAlive())
{
th.out.writeUTF("用户离线:"+name)
}
}
catch(IOException eee)
{
}
}
peopleList.remove(name)
try
{
socket.close()
}
catch(IOException eee)
{
}
System.out.println(name+"用户离开了")
break
}
}
}
}
import java.awt.*
import java.io.*
import java.net.*
import java.applet.*
import java.util.Hashtable
ClientChat.java
public class ClientChat extends Applet implements Runnable
{
Socket socket=null
DataInputStream in=null
DataOutputStream out=null
InputNameTextField 用户提交昵称界面=null
ChatArea 用户聊天界面=null
Hashtable listTable
Label 提示条
Panel north, center
Thread thread
public void init()
{
int width=getSize().width
int height=getSize().height
listTable=new Hashtable()
setLayout(new BorderLayout())
用户提交昵称界面=new InputNameTextField(listTable)
int h=用户提交昵称界面.getSize().height
用户聊天界面=new ChatArea("",listTable,width,height-(h+5))
用户聊天界面.setVisible(false)
提示条=new Label("正在连接到服务器,请稍等...",Label.CENTER)
提示条.setForeground(Color.red)
north=new Panel(new FlowLayout(FlowLayout.LEFT))
center=new Panel()
north.add(用户提交昵称界面)
north.add(提示条)
center.add(用户聊天界面)
add(north,BorderLayout.NORTH)
add(center,BorderLayout.CENTER)
validate()
}
public void start()
{
if(socket!=null&&in!=null&&out!=null)
{ try
{
socket.close()
in.close()
out.close()
用户聊天界面.setVisible(false)
}
catch(Exception ee)
{
}
}
try
{
socket = new Socket(this.getCodeBase().getHost(), 6666)
in=new DataInputStream(socket.getInputStream())
out=new DataOutputStream(socket.getOutputStream())
}
catch (IOException ee)
{
提示条.setText("连接失败")
}
if(socket!=null)
{
InetAddress address=socket.getInetAddress()
提示条.setText("连接:"+address+"成功")
用户提交昵称界面.setSocketConnection(socket,in,out)
north.validate()
}
if(thread==null)
{
thread=new Thread(this)
thread.start()
}
}
public void stop()
{
try
{
socket.close()
thread=null
}
catch(IOException e)
{
this.showStatus(e.toString())
}
}
public void run()
{
while(thread!=null)
{
if(用户提交昵称界面.get能否聊天()==true)
{
用户聊天界面.setVisible(true)
用户聊天界面.setName(用户提交昵称界面.getName())
用户聊天界面.setSocketConnection(socket,in,out)
提示条.setText("祝聊天愉快!")
center.validate()
break
}
try
{
Thread.sleep(100)
}
catch(Exception e)
{
}
}
}
}
InputNameTextField。java
import java.awt.*
import java.net.*
import java.awt.event.*
import java.io.*
import java.util.Hashtable
public class InputNameTextField extends Panel implements ActionListener,Runnable
{
TextField nameFile=null
String name=null
Checkbox male=null,female=null
CheckboxGroup group=null
Button 进入聊天室=null,退出聊天室=null
Socket socket=null
DataInputStream in=null
DataOutputStream out=null
Thread thread=null
boolean 能否聊天=false
Hashtable listTable
public InputNameTextField(Hashtable listTable)
{
this.listTable=listTable
nameFile=new TextField(10)
group=new CheckboxGroup()
male=new Checkbox("男",true,group)
female=new Checkbox("女",false,group)
进入聊天室=new Button("进入")
退出聊天室=new Button("退出")
进入聊天室.addActionListener(this)
退出聊天室.addActionListener(this)
thread=new Thread(this)
add(new Label("昵称:"))
add(nameFile)
add(male)
add(female)
add(进入聊天室)
add(退出聊天室)
退出聊天室.setEnabled(false)
}
public void set能否聊天(boolean b)
{
能否聊天=b
}
public boolean get能否聊天()
{
return 能否聊天
}
public String getName()
{
return name
}
public void setName(String s)
{
name=s
}
public void setSocketConnection(Socket socket,DataInputStream in,DataOutputStream out)
{
this.socket=socket
this.in=in
this.out=out
try{
thread.start()
}
catch(Exception e)
{
nameFile.setText(""+e)
}
}
public Socket getSocket()
{
return socket
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==进入聊天室)
{
退出聊天室.setEnabled(true)
if(能否聊天==true)
{
nameFile.setText("您正在聊天:"+name)
}
else
{
this.setName(nameFile.getText())
String sex=group.getSelectedCheckbox().getLabel()
if(socket!=null&&name!=null)
{
try{
out.writeUTF("姓名:"+name+"性别:"+sex)
}
catch(IOException ee)
{
nameFile.setText("没有连通服务器"+ee)
}
}
}
}
if(e.getSource()==退出聊天室)
{
try
{
out.writeUTF("用户离开:")
}
catch(IOException ee)
{
}
}
}
public void run()
{
String message=null
while(true)
{
if(in!=null)
{
try
{
message=in.readUTF()
}
catch(IOException e)
{
nameFile.setText("和服务器断开"+e)
}
}
if(message.startsWith("可以聊天:"))
{
能否聊天=true
break
}
else if(message.startsWith("聊天者:"))
{
String people=message.substring(message.indexOf(":")+1)
listTable.put(people,people)
}
else if(message.startsWith("不可以聊天:"))
{
能否聊天=false
nameFile.setText("该昵称已被占用")
}
}
}
}