王朝网络
分享
 
 
 

聊天室--java socket

王朝java/jsp·作者佚名  2006-01-09
宽屏版  字体: |||超大  

这是我用java socket写的一个简单的聊天室程序,以下是我的设计文档和源代码:

ChatRoom 聊天室设计文档

客户端和服务器界面:

客户端

服务器端

ChatRoom 聊天室程序功能简介:

服务器接受每个连接客户发来的信息,再广播给每个客户。

Server:

服务器 ChatRoomServer 启动后自动监听默认端口:DEFAULT_PORT 6666等待客户的连接,当有客户连接上来时,在文本域显示连接信息。

服务器端点击窗口关闭或点击窗体内的退出按钮可以关闭服务器。

Client:

客户端ChatRoomClient 启动后显示客户端界面:窗体上方有一个“连接”按钮和一个文本筐(文本筐在按钮的右面)。在文本筐中输入服务器地址,再按左边的“连接”按钮或按键盘上的”Enter”键,连接服务器。如果连接成功将显示连接成功信息,否则将显示连接失败信息。

连接成功后客户可以在窗体底部消息标签右边的文本筐中输入要发送的消息,然后点击文本筐右边的“发送“按钮或按键盘上的”Enter“键发送信息。

客户端受到的信息将显示在窗体中部的文本域中。

ChatRoomServer.java——说明:

//由于在程序中做了较多注释,所以这里只做简单的叙述:

1.程序启动是初始化界面、并开始监听:

public ChatRoomServer(){

try{

jbInit();

}catch(Exception e){

e.printStackTrace();

}

serverListen();//服务器开始监听

}

jbInit(){、、、、}初始化界面,注册button1(退出)按钮和窗口关闭事件。

serverListen(){、、、}打开并监听端口:6666,

2.public void run(){//接受连接并记录线程信息

、、、、、、

try{

while(true){

Socket clientSock=serverSock.accept();

CommunicateThread ct=new CommunicateThread(clientSock,this,index);//创建线程保持连接

clients.add(ct);//记录连接信息到clients数组

clientsInfor.add("Thread-"+i);//记录连接名称

、、、、、、、、、

}

CommunicateThread ct=new CommunicateThread(clientSock,this,index);

当有连接上来时,创建线程以保持连接。

3.public void exit(){、、、}

退出并关闭seversock

4.class CommunicateThread extends Thread{、、、、}//保持连接线程

5. class BroadcastThread extends Thread{、、、}//广播线程

6.//处理窗口关闭事件的适配器

class ChatFrame_WindowAdapter extends java.awt.event.WindowAdapter{、、、}

ChatRoomClient.java——说明:

1. 初始化窗体

public ChatRoomClient(){

try{

jbInit();

}catch(Exception e){

e.printStackTrace();

}

}

jbInit(){、、、、}初始化窗体,将button1(连接)、button2(发送)注册到ActionListener,将textField1(服务器地址) 、textField2(消息)注册到keyListener,将窗体注册到WindowListener。

2. StartConnect(){、、、、}//连接服务器

点击button1或在textField1中按“Enter”键后调用startConnect()连接服务器并启动线程run(),读取服务器广播来的信息,打印到文本区域。

3.public void exit(){、、、}//窗口关闭;如果有连接则关闭连接和相关的"流"

4.//文本筐textField1的键击事件适配器

class textField1_KeyAdapter extends java.awt.event.KeyAdapter{}

5.//文本筐textField2的键击事件适配器

class textField2_KeyAdapter extends java.awt.event.KeyAdapter{}

6.//窗口关闭事件适配器

class ChatFrame_WindowAdapter extends java.awt.event.WindowAdapter{}

聊天室服务器端源程序:

package chatserver2;

//Chat Room Server

//this software is designed by Chen Heping(陈和平)

import java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.net.*;

public class ChatRoomServer extends Frame implements Runnable{

Panel panel;

ScrollPane sPanel;

TextArea textArea;

Button button1;

//net

ServerSocket serverSock;

public final static int DEFAULT_PORT=6666;//默认端口号

Thread chatAcceptThread;//启动接受连接的线程

BroadcastThread broadcastThread;//广播thread; run when server is listening

java.util.Vector clients;//记录连接的线程

java.util.Vector clientsInfor;//记录连接线程的信息

public static int index=0;

public ChatRoomServer(){

try{

jbInit();

}catch(Exception e){

e.printStackTrace();

}

serverListen();//服务器开始监听

}

private void jbInit(){//初始化界面

panel=new Panel();

sPanel=new ScrollPane();

textArea=new TextArea("server information:\n");

button1=new Button("退出");

sPanel.add(textArea);

button1.addActionListener(new java.awt.event.ActionListener(){//退出按钮注册

public void actionPerformed(ActionEvent e){

button1_actionPerformed(e);

}

});

panel.add(button1);

this.addWindowListener(new ChatFrame_WindowAdapter(this));//注册到继承了窗口适配器的类

this.setSize(600,600);

this.setLayout(new BorderLayout());

this.add(sPanel,BorderLayout.CENTER);

this.add(panel,BorderLayout.SOUTH);

this.show();

}

private void button1_actionPerformed(ActionEvent e){

exit();

}

public void processMsg(String str){//

textArea.append(str);

}

private void serverListen(){

try{

serverSock=new ServerSocket(DEFAULT_PORT);

}catch(IOException e){

processMsg(e.toString());

processMsg("server failed!\n");

}

processMsg("server listening on port:"+DEFAULT_PORT);

clients=new java.util.Vector();

clientsInfor=new java.util.Vector();

chatAcceptThread=new Thread(this);//启动接受连接的线程

chatAcceptThread.start();

broadcastThread=new BroadcastThread(this);//广播线程

broadcastThread.start();

//还有一个回收无用连接thread 的线程

}

public void run(){//接受连接并记录线程信息

int i=0;

try{

while(true){

Socket clientSock=serverSock.accept();

CommunicateThread ct=new CommunicateThread(clientSock,this,index);//创建线程保持连接

clients.add(ct);//record Communicate Thread;

i++;

index++;//version2

clientsInfor.add("Thread-"+i);

processMsg("Thread-"+i+"join in\n");

}

}catch(IOException e){

processMsg(e.toString());

}

}

public void exit(){

broadcastThread.broadcast("Server exit!");

try{

serverSock.close();

}catch(IOException ioe){}

finally{

System.exit(0);

}

}

public static void main(String[] args){

ChatRoomServer chat=new ChatRoomServer();

}

}

class CommunicateThread extends Thread{//保持连接线程

protected Socket clientSock;

protected BufferedReader in=null;

protected PrintWriter out;

ChatRoomServer chatFrame;

boolean isTrue=true;//run()

java.util.Vector inforStack;

int index2;//

public CommunicateThread(Socket Sock,ChatRoomServer cFrame,int index){

clientSock=Sock;

chatFrame=cFrame;

index2=index;

inforStack=new java.util.Vector();

try{

in=new BufferedReader(new InputStreamReader(clientSock.getInputStream()));

out=new PrintWriter(clientSock.getOutputStream());

}catch(IOException ei){

try{

clientSock.close();

}catch(IOException ei2){ }

chatFrame.processMsg(ei.toString());

return;

}

this.start();

}

public void run(){

String infor;

try{

while(isTrue){

infor=in.readLine();

if(infor.equals("Client exit!")){

writeInformation(infor);//把信息写到信息栈,以倍广播出去

stopRun();

}else if(infor!=null){

writeInformation(infor);

}//else break;

try{

Thread.sleep(100);//version2

}catch(InterruptedException ex){}

}

}catch(IOException e){ ;}

finally{

try{

in.close();

out.close();

clientSock.close();

chatFrame.clients.remove(index2);//在clients中清除本线程序

ChatRoomServer.index--;//

}catch(IOException ei){;}

}

}

public void writeInformation(String infor){//写信息栈

inforStack.add(infor);

}

private void stopRun(){//终止线程

isTrue=false;

}

public void sendInformation(String str){//发送信息

try{

out.println(str);

out.flush();

}catch(Exception e){;}

}

}

class BroadcastThread extends Thread{//广播线程

ChatRoomServer chatFrame2;

java.util.Vector chatClients;//连接线程信息

java.util.Vector msgStack;//信息栈

java.util.Vector clientMsg;//记录客户发送的信息

CommunicateThread comThread1;

CommunicateThread comThread2;

String string;//information in inforStack

String clientName;//client thread name

String broadcastInfor;//broadcast information=clientName+string;

public BroadcastThread(ChatRoomServer cFrame){

chatFrame2=cFrame;

chatClients=chatFrame2.clients;

clientMsg=chatFrame2.clientsInfor;

//this.start();

}

public void broadcast(String str){//广播

for(int k=0;k<chatClients.size();k++){//send to everyone分别调用每个连接线程,发送信息

comThread2=(CommunicateThread)chatClients.get(k);

comThread2.sendInformation(str);

}

}

public void run(){

try{

while(true){

for(int i=0;i<chatClients.size();i++){

comThread1=(CommunicateThread)chatClients.get(i);

msgStack=comThread1.inforStack;//得到每个连接的信息栈

clientName=(String)clientMsg.get(i);//客户名

//读取每个连接线程的信息栈并把信息发送出去

for(int j=0;j<msgStack.size();j++){

string=(String)msgStack.get(j);

broadcastInfor=clientName+"->"+string;

broadcast(broadcastInfor);

}

//clear the inforStack

msgStack.removeAllElements();//清除以发送的信息

}

try{

Thread.sleep(100);//version2

}catch(InterruptedException ex){}

}

}catch(Exception e){}

}

}

//处理窗口关闭事件的适配器

class ChatFrame_WindowAdapter extends java.awt.event.WindowAdapter{

ChatRoomServer chatFrame;

public ChatFrame_WindowAdapter(ChatRoomServer chatFrame){

this.chatFrame=chatFrame;

}

public void windowClosing(WindowEvent e){//exit program

chatFrame.exit();//reference to the method exit() in ChatRoomServer.

}

}

聊天室客户端源程序:

package chatclient_test;

//ChatRoomClient

//designed by Chen Heping(陈和平)

import java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.net.*;

public class ChatRoomClient extends Frame implements Runnable{

Panel panel1,panel2;

Button button1,button2;

TextField textField1,textField2;

Label label1;

TextArea textArea;

ScrollPane sPanel;

//net

PrintWriter out;

BufferedReader in=null;

Socket sock;

public final static int DEFAULT_PORT=6666;

//create Thread to Read information from Server

Thread readThread;

boolean isTrue=true;//thread can go on runing ??

public ChatRoomClient(){

try{

jbInit();

}catch(Exception e){

e.printStackTrace();

}

}

public static void main(String[] args){//main method

ChatRoomClient c=new ChatRoomClient();

c.show();

}

private void jbInit(){//should set size,position and Font of every component

button1=new Button("连接");// set Font

button2=new Button("发送");

textField1=new TextField("input Server address here!");

textField2=new TextField("input Message here and send to server");

label1=new Label("消息:");

panel1=new Panel();

panel2=new Panel();

sPanel=new ScrollPane();

textArea=new TextArea();

//panel1

//press button1: 连接 to connect the client to server

button1.addActionListener(new java.awt.event.ActionListener(){

public void actionPerformed(ActionEvent e){

button1_actionPerformed(e);

}

});

//textField1:for input the address of server;be registered to KeyListener.

//press key:Enter to connect the client to server

textField1.addKeyListener(new textField1_KeyAdapter(this));//java.awt.event.KeyAdapter()

panel1.add(button1);

panel1.add(textField1);

//sPanel ScrollPane

sPanel.add(textArea);

//panel2

//press button2: 发送 to send message

button2.addActionListener(new java.awt.event.ActionListener(){

public void actionPerformed(ActionEvent e){

button2_actionPerformed(e);

}

});

//textField2:for input message;be registered to KeyListener.

//press key:Enter to send message

textField2.addKeyListener(new textField2_KeyAdapter(this));

panel2.add(label1);

panel2.add(textField2);

panel2.add(button2);

//frame

this.addWindowListener(new ChatFrame_WindowAdapter(this));//frame is registered to WindowListener

this.setLayout(new BorderLayout());

this.setSize(500,400);

this.add(panel1,BorderLayout.NORTH);

this.add(sPanel,BorderLayout.CENTER);

this.add(panel2,BorderLayout.SOUTH);

//this.show()

}

public void startConnect(){//开始连接

try{

sock=new Socket(textField1.getText(),DEFAULT_PORT);

if(sock!=null){//connection successed

processMsg("Connect successfully!");

}

in=new BufferedReader(new InputStreamReader(sock.getInputStream()));

out=new PrintWriter(sock.getOutputStream());

}catch(IOException ex){

processMsg(ex.toString());

processMsg("Connect failed!");

}

readThread=new Thread(this);

readThread.start();

}

//public void endConnect(){//close IOstream

public void sendInformation(){

out.println(textField2.getText());

out.flush();

}

private void button1_actionPerformed(ActionEvent e){//连接按钮

startConnect();

}

private void button2_actionPerformed(ActionEvent e){//发送按钮

sendInformation();

}

public void stopRun(){//to stop the running thread

isTrue=false;

}

public void processMsg(String msg){//客户端处理消息

textArea.append(msg);

textArea.append("\n");

}

public void run(){

String msg;

isTrue=true;

while(isTrue){

try{

msg=in.readLine();

if(msg.equals("Server exit!")){//server exit

processMsg(msg);

stopRun();//终止线程

}else if(msg!=null){

processMsg(msg);

}

Thread.sleep(1000);

}catch(IOException e){

processMsg(e.toString());

}catch(InterruptedException ei){

processMsg(ei.toString());

}

}

//endConnect();

try{//服务器退出关闭连接和相关的"流"

sock.close();

in.close();

out.close();

}catch(IOException ioe){}

}

public void exit(){//窗口关闭;如果有连接则关闭连接和相关的"流"

try{//send "Client exit!" to Server!

out.println("Client exit!");

out.flush();

}catch(Exception exc){}

//endConnect();

try{//close IOstream

sock.close();

in.close();

out.close();

}catch(IOException ioe){}

finally{

System.exit(0);

}

}

}

//文本筐textField1的键击事件适配器

class textField1_KeyAdapter extends java.awt.event.KeyAdapter{

ChatRoomClient chatFrame;

public textField1_KeyAdapter(ChatRoomClient chatFrame){

this.chatFrame=chatFrame;

}

public void keyPressed(KeyEvent e){//输入的是enter,开始连接!

int j=e.getKeyCode();

if(j==e.VK_ENTER){

chatFrame.startConnect();

}

}

}

//文本筐textField2的键击事件适配器

class textField2_KeyAdapter extends java.awt.event.KeyAdapter{

ChatRoomClient chatFrame;

public textField2_KeyAdapter(ChatRoomClient chatFrame){

this.chatFrame=chatFrame;

}

public void keyPressed(KeyEvent e){//键击Enter键,发送信息!

int j=e.getKeyCode();

if(j==e.VK_ENTER){

chatFrame.sendInformation();

}

}

}

//窗口关闭事件适配器

class ChatFrame_WindowAdapter extends java.awt.event.WindowAdapter{

ChatRoomClient chatFrame;

public ChatFrame_WindowAdapter(ChatRoomClient chatFrame){

this.chatFrame=chatFrame;

}

public void windowClosing(WindowEvent e){//exit program

chatFrame.exit();//reference to the method exit() in ChatRoomClient.

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有