import java.applet.*
import java.awt.*
import java.io.*
import java.net.*
import java.awt.event.*
public class ChatClient extends Applet{
protected boolean loggedIn//登入状态
protected Frame cp//聊天室框架
protected static int PORTNUM=7777//缺省端口号7777
protected int port//实际端口号
protected Socket sock
protected BufferedReader is//用于从sock读取数据的BufferedReader
protected PrintWriter pw//用于向sock写入数据的PrintWriter
protected TextField tf//用于输入的TextField
protected TextArea ta//用于显示对话的TextArea
protected Button lib//登入按钮
protected Button lob//登出的按钮
final static String TITLE ="Chatroom applet>>>>>>>>>>>>>>>>>>>>>>>>"
protected String paintMessage//发表的消息
public ChatParameter Chat
public void init(){
paintMessage="正在生成聊天窗口"
repaint()
cp=new Frame(TITLE)
cp.setLayout(new BorderLayout())
String portNum=getParameter("port")//呢个参数勿太明
port=PORTNUM
if (portNum!=null) //书上是portNum==null,十分有问题
port=Integer.parseInt(portNum)
//CGI
ta=new TextArea(14,80)
ta.setEditable(false)//read only attribute
ta.setFont(new Font("Monospaced",Font.PLAIN,11))
cp.add(BorderLayout.NORTH,ta)
Panel p=new Panel()
Button b
//for login button
p.add(lib=new Button("Login"))
lib.setEnabled(true)
lib.requestFocus()
lib.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
login()
lib.setEnabled(false)
lob.setEnabled(true)
tf.requestFocus()//将键盘输入锁定再右边的文本框中
}
})
//for logout button
p.add(lob=new Button ("Logout"))
lob.setEnabled(false)
lob.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
logout()
lib.setEnabled(true)
lob.setEnabled(false)
lib.requestFocus()
}
})
p.add(new Label ("输入消息:"))
tf=new TextField(40)
tf.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(loggedIn){
//pw.println(Chat.CMD_BCAST+tf.getText())//Chat.CMD....是咩野来?
int j=tf.getText().indexOf(":")
if(j>0) pw.println(Chat.CMD_MESG+tf.getText())
else
pw.println(Chat.CMD_BCAST+tf.getText())
tf.setText("")//勿使用flush()?
}
}
})
p.add(tf)
cp.add(BorderLayout.SOUTH,p)
cp.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
//如果执行了setVisible或者dispose,关闭窗口
ChatClient.this.cp.setVisible(false)
ChatClient.this.cp.dispose()
logout()
}
})
cp.pack()//勿明白有咩用?
//将Frame cp放在中间
Dimension us=cp.getSize(),
them=Toolkit.getDefaultToolkit().getScreenSize()
int newX=(them.width-us.width)/2
int newY=(them.height-us.height)/2
cp.setLocation(newX,newY)
cp.setVisible(true)
paintMessage="Window should now be visible"
repaint()
}
//登录聊天室
public void login(){
if(loggedIn) return
try{
sock=new Socket(getCodeBase().getHost(),port)
is=new BufferedReader(new InputStreamReader(sock.getInputStream()))
pw=new PrintWriter(sock.getOutputStream(),true)
}catch(IOException e){
showStatus("Can't get socket: "+e)
cp.add(new Label("Can't get socket: "+e))
return}
//构造并且启动读入器,从服务器读取数据,输出到文本框中
//这里,长成一个线程来避免锁住资源(lockups)
new Thread (new Runnable(){
public void run(){
String line
try{
while(loggedIn &&((line=is.readLine())!=null))
ta.appendText(line+"\n")
}catch(IOException e){
showStatus("我的天啊,掉线了也!!!!")
return
}
}
}).start()
//假定登录(其实只是打印相关信息,并没有真正登录)
// pw.println(Chat.CMD_LOGIN+"AppletUser")
pw.println(Chat.CMD_LOGIN+"AppletUser")
loggedIn =true
}
//模仿退出的代码
public void logout(){
if(!loggedIn)
return
loggedIn=false
try{
if(sock!=null)
sock.close()
}catch(IOException ign){
// 异常处理哦
}
}
//没有设置stop的方法,即使从浏览器跳到另外一个网页的时候
//聊天程序还可以继续运行
public void paint(Graphics g){
Dimension d=getSize()
int h=d.height
int w=d.width
g.fillRect(0,0,w,2)
g.setColor(Color.black)
g.drawString(paintMessage,10,(h/2)-5)
}
}
聊天室服务器端
import java.net.*
import java.io.*
import java.util.*
public class ChatServer{
//聊天室管理员ID
protected final static String CHATMASTER_ID="ChatMaster"
//系统信息的分隔符
protected final static String SEP=": "
//服务器的Socket
protected ServerSocket servSock
//当前客户端列表
protected ArrayList clients
//调试标记
protected boolean DEBUG=false
public ChatParameter Chat
//主方法构造一个ChatServer,没有返回值
public static void main(String[] argv){
System.out.println("Chat server0.1 starting>>>>>>>>>>>>>>>>")
ChatServer w=new ChatServer()
w.runServer()
System.out.println("***ERROR*** Chat server0.1 quitting")
}
//构造和运行一个聊天服务
ChatServer(){
Chat=new ChatParameter()
clients=new ArrayList()
try{
servSock=new ServerSocket(7777)//实有问题拉,不过可能是他自己定义既一个class.
System.out.println("Chat Server0.1 listening on port:"+7777)
}catch(Exception e){
log("IO Exception in ChatServer.<init>")
System.exit(0)
}
}
public void runServer(){
try{
while(true){
Socket us=servSock.accept()
String hostName=us.getInetAddress().getHostName()
System.out.println("Accpeted from "+hostName)
//一个处理的线程
ChatHandler cl=new ChatHandler(us,hostName)
synchronized(clients){
clients.add(cl)
cl.start()
if(clients.size()==1)
cl.send(CHATMASTER_ID,"Welcome!You are the first one here")
else{
cl.send(CHATMASTER_ID,"Welcome!You are the latest of"+
clients.size()+" users.")
}
}
}
}catch(Exception e){
log("IO Exception in runServer:"+e)
System.exit(0)
}
}
protected void log(String s){
System.out.println(s)
}
//处理会话的内部的类
protected class ChatHandler extends Thread {
//客户端scoket
protected Socket clientSock
//读取socket的BufferedReader
protected BufferedReader is
//在socket 上发送信息行的PrintWriter
protected PrintWriter pw
//客户端出主机
protected String clientIP
//句柄
protected String login
public ChatHandler (Socket sock,String clnt)throws IOException {
clientSock=sock
clientIP=clnt
is=new BufferedReader(
new InputStreamReader(sock.getInputStream()))
pw=new PrintWriter (sock.getOutputStream(),true)
}
//每一个ChatHandler是一个线程,下面的是他的run()方法
//用于处理会话
public void run(){
String line
try{
while((line=is.readLine())!=null){
char c=line.charAt(0)//我顶你老母啊 ,果只Chat.CMD咩xx冇定义 扑啊///!!!
line=line.substring(1)
switch(c){
//case Chat.CMD_LOGIN:
case 'l':
if(!Chat.isValidLoginName(line)){
send(CHATMASTER_ID,"LOGIN"+line+"invalid")
log("LOGIN INVALID from:"+clientIP)
continue
}
login=line
broadcast(CHATMASTER_ID,login+" joins us,for a total of"+
clients.size()+" users")
break
// case Chat.CMD_MESG:
case 'm':
if(login==null){
send(CHATMASTER_ID,"please login first")
continue
}
int where =line.indexOf(Chat.SEPARATOR)
String recip=line.substring(0,where)
String mesg=line.substring (where+1)
log("MESG: "+login+"--->"+recip+": "+mesg)
ChatHandler cl=lookup(recip)
if(cl==null)
psend(CHATMASTER_ID,recip+"not logged in.")
else
cl.psend(login,mesg)
break
//case Chat.CMD_QUIT:
case 'q':
broadcast(CHATMASTER_ID,"Goodbye to "+login+"@"+clientIP)
close()
return//ChatHandler结束
// case Chat.CMD_BCAST:
case 'b':
if(login!=null)
broadcast(login,line)
else
log("B<L FROM"+clientIP)
break
default:
log("Unknow cmd"+c+"from"+login+"@"+clientIP)
}
}
}catch(IOException e){
log("IO Exception :"+e)
}finally{
//sock 结束,我们完成了
//还不能发送再见的消息
//得有简单的基于命令的协议才行
System.out.println(login+SEP+"All Done")
synchronized(clients){
clients.remove(this)
if(clients.size()==0){
System.out.println(CHATMASTER_ID+SEP+
"I'm so lonely I could cry>>>>>")
}else if(clients.size()==1){
ChatHandler last=(ChatHandler)clients.get(0)
last.send(CHATMASTER_ID,"Hey,you are talking to yourself again")
}
else{
broadcast(CHATMASTER_ID,"There are now"+clients.size()+" users")
}
}
}
}
protected void close(){
if(clientSock==null){
log("close when not open")
return
}
try{
clientSock.close()
clientSock=null
}catch(IOException e){
log("Failure during close to "+clientIP)
}
}
//发送一条消息给用户
public void send(String sender,String mesg){
pw.println(sender+SEP+"*>"+mesg)
}
//发送私有的消息
protected void psend(String sender ,String msg){
send("<*"+sender+"*>",msg)
}
//发送一条消息给所有的用户
public void broadcast (String sender,String mesg){
System.out.println("Broadcasting"+sender+SEP+mesg)
for(int i=0i<clients.size()i++){
ChatHandler sib=(ChatHandler)clients.get(i)
if(DEBUG)
System.out.println("Sending to"+sib)
sib.send(sender,mesg)
}
if(DEBUG) System.out.println("Done broadcast")
}
protected ChatHandler lookup(String nick){
synchronized(clients){
for(int i=0i<clients.size()i++){
ChatHandler cl=(ChatHandler)clients.get(i)
if(cl.login.equals(nick))
return cl
}
}
return null
}
//将ChatHandler对象转换成一个字符串
public String toString(){
return "ChatHandler["+login+"]"
}
}
}
public class ChatParameter {
public static final char CMD_BCAST='b'
public static final char CMD_LOGIN='l'
public static final char CMD_MESG='m'
public static final char CMD_QUIT='q'
public static final char SEPARATOR=':'//?????
public static final int PORTNUM=7777
public boolean isValidLoginName(String line){
if (line.equals("CHATMASTER_ID"))
return false
return true
}
public void main(String[] argv){
}
}
记得加分啊!!!
1.创建index.asp页面<html>
<frameset rows="60,*">
<frame name="say" src="say.asp">
<frame name="message" src="message.asp">
</frameset><noframes></noframes>
</html>
2.创建say.asp页面
<html>
<body>
<form name="form1" method="post" action="">
昵称:<input type="text" name="txtName" size="10">
发言:<input type="text" name="txtSay" size="30">
<input type="submit" value=" 发送 ">
</form>
<%
'如果提交了表单,就将发言内容添加到Application对象中
If Trim(Request.Form("txtName"))<>"" And Trim(Request.Form("txtSay"))<>"" Then
'下面先获取发言人的IP地址
User_ip=Request.ServerVariables("Remote_Addr")
'下面获取本次发言字符串,包括发言人和发言内容
Dim strSay
strSay="来自于"&User_ip&"的" &Request.Form("txtName") &"在" &Now()&"说:" &Request.Form("txtSay") &"<br>"
'下面将本次发言添加到聊天内容中
Application.Lock '先锁定
Application("strChat")=strSay &Application("strChat")
Application.Unlock '解除锁定
End if
%>
</body>
</html>
3.创建message.asp页面
<html>
<head>
<title>显示发言页面</title>
<meta http-equiv="refresh" content="5">
</head>
<body>
<% Response.Write Application("strChat") '显示聊天内容 %>
</body>
</html>