推技术socket聊天室,基础问题,附简单易懂源码

foolfish 2005-04-17 09:17:47
我要实现一秒向客户端浏览器输出一个ok
目前的情况是使用while((newLine = input.readLine()) != null);保持住客户端输出流,连第一个ok都无法输出,除非关闭该socket

以下为全部代码.请看看有啥问题.


import java.io.*;
import java.net.*;

public class ChatServer {
public static void Start(){
Socket socketClient = null;
ServerSocket socketServer = null;
try{
socketServer = new ServerSocket(999,50);
}catch(IOException ex)
{}
while(true){
do{
java.net.Socket s=null;
try{
s= socketServer.accept();
}catch(IOException ex)
{}
ClientThread w = new ClientThread(s);
(new Thread(w, "additional worker")).start();
} while(true);
}
}
public static void main(String args[]){
Start();
}
}

class ClientThread implements Runnable {//extends Thread {
Socket client;
public ClientThread(Socket socket){
client = socket;
}
public void run()
{
try{
BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintStream output = new PrintStream(client.getOutputStream());
if(printHeaders(output)){
output.print("ok");
//client.close(); return; //如在这里关闭socket,则可以正常输出


//以下代码要实现一秒向客户浏览器输出一个"ok",可目前的代码一个都输不出..
String newLine;
try{
while((newLine = input.readLine()) != null);
}
catch(SocketException e) { }

client.close();
return;
}
}catch(IOException ex)
{}
}
boolean printHeaders(PrintStream ps)
throws IOException
{
return printHeaders(ps, null);
}

boolean printHeaders(PrintStream ps, String newHeaders)
{
boolean ret = false;
ret = true;
String headers = "HTTP/1.0 200 OK\r\nServer: OpenCHAT Server\r\nDate: " + new java.util.Date() + "\r\n" + "Connection: keep-alive\r\n" + "Cache-Control: no-cache,no-store,max-age=0\r\n" + "Pragma: no-cache\r\n" + "Content-type: text/html; charset=gbk\r\n\r\n";
ps.write(headers.getBytes(), 0, headers.length());
return ret;
}
}
...全文
417 点赞 收藏 23
写回复
23 条回复
foolfish 2005年04月18日
hapybird(hapybird)
强啊,Echat我用过,后来改用Fchat,因为可以连接IDBC :#)

程序我是使劲简化了放上的,为了看的清楚,
我想问题可能出在 output.flush()或者socket.setsotimeout(0)这样的方法上
可我把output.flush()放在任何地方都无法输出内容

能不能帮我修改一下顶楼的代码达到我要的功能?分一定全部送上,谢谢!
回复 点赞
hapybird 2005年04月18日
XMLHTTP我倒没见过用
回复 点赞
hapybird 2005年04月18日
XMLHTTP 现在国内做的socket据我所知都是我刚才说的原理,比如啥ichat,tom的chat,sina 的chat,163的chat,这种东西的好处是效率高,资源少,速度快。
回复 点赞
hapybird 2005年04月18日
我以前写过,开始用perl写的,当时有个echat,perl版本的就是我写的,某些信息港用的在线人数2000多,后来用java写了个简单的,也可以用,但是没完善功能。
以前java实现的机制和c++以及其他的不是很一样,用的是线程,而unix里面可以用select socket的,单线程来处理,这样子效率最高,cpu使用率最高。不过以前java限制没有select socket类,所以只能用线程处理。你的基本的思路是对的,但是在系统的结构上要调整下。
1、怎么保持http连接不断,确实没错,要每隔多少时间向客户段输出个数据,比如<!>,这个时间每个人不一样,这是根据IE的超时时间决定的,一般10秒-20秒差不多了,不过你少写了一个flush()方法,所以没有输出。
2、这种hold on socket的事情不要给每个socket分个线程来做,在有新的连接进来,处理完当前请求后,如果是主窗口的socket,则把它加进一个hashmap即可,让另外一个线程来循环 hold on 所有的socket,其他的请求处理完则关掉。
回复 点赞
foolfish 2005年04月18日
好的,我不会删的.
总之,谢谢你 :)
回复 点赞
abcdhy 2005年04月18日
现在的年轻人啊!!!
我无话可说了!

公道自在人心!!!!

希望你不要删贴子, 自有后来人知道!!!
回复 点赞
foolfish 2005年04月18日
abcdhy(程旭) 对你无话可说了...XMLHTTP都出来了 - -
你懂socket么?对自己一无所知的东西就不要瞎扯.这里不是招聘会.别把人都想得比你傻.
回复 点赞
abcdhy 2005年04月18日

看来你真是对 HTTP 不了解啊!!

IE 向 WEB Server 请求一个网址,在接受到全部的内容后,就断开连接.
至于如何才是接受到了全部的内容,HTTP 规范有定义的.
如果服务器,没有发送一个完整的 HTTP 内容,IE 不知道内容已经结束,(就象你做的一样). 服务器就必须自己断开 连接 , 要不 IE 会一直 Loading , 因为 IE 不知道"内容已经结束了"

这就是为什么, socket.close();或者PrintStream .close()把流或者socket关闭,否则之前print的内容在客户浏览器根本无法显示出来,IE一直是loading的状态. 的原因.

你用 javascript的frame.reload()一下,就可以正常达到效果了
那是 IE 已经放弃了前一次请求的内容,又新一次请求内容了,当然能刷新一下,但还是会一直 loading .

而且使用 frame.reload() 实现,会有明显的闪烁, 效果不好, 使用 XMLHTTP 才是正确的方法.

多学点基础知识吧!!!!
回复 点赞
answerooo 2005年04月18日
回复 点赞
foolfish 2005年04月18日
XMLHTTP跟socket一点关系没有,是浏览器的一个对象,类似浏览器-服务器的中间件,处理请求,达到无刷新的效果,楼上那位的意思还是普通的聊天室,用XMLHTTP的方法去取page中的聊天内容然后用javascript innerHTML到聊天内容框.真是寒到我不行啊...
回复 点赞
foolfish 2005年04月18日
XMLHTTP是前台的东西,属于美工做的,我对此没有兴趣 :)
回复 点赞
foolfish 2005年04月17日
abcdhy(程旭)
呵呵, 我用 socket 的 IE 做客户端, 和 使用 Java swing 做客户端的都写过.
建议你 看看 HTTP 协议.
了解 IE 的工作过程



hehe,你这么厉害连一秒向客户IE push一个ok就认为无法做到?
那你能否解释为什么我点一下刷新就正常了呢?
照你的逻辑网易的聊天室又是如何做成的? - -
回复 点赞
abcdhy 2005年04月17日
呵呵, 我用 socket 的 IE 做客户端, 和 使用 Java swing 做客户端的都写过.

建议你 看看 HTTP 协议.

了解 IE 的工作过程
回复 点赞
foolfish 2005年04月17日
abcdhy(程旭)
不是的,你有没有写过socket的聊天室?

而且目前我的情况是前台用 javascript的frame.reload()一下,就可以正常达到效果了
回复 点赞
abcdhy 2005年04月17日
晕,不早说客户端是 IE ,
看来你得去多了解 HTTP 协议了.
呵呵, 这和普通的 socket 编程有点不同的哦!

问题就是目前除非我使用
socket.close();或者PrintStream .close()把流或者socket关闭,否则之前print的内容在客户浏览器根本无法显示出来,IE一直是loading的状态.
呵呵
这是 HTTP 协议决定的! 没有其他办法.

回复 点赞
wjvonline 2005年04月17日
什么哦,没搞懂
回复 点赞
foolfish 2005年04月17日
就是一秒向客户端输出一个ok

输出结果就是
okokokokokokokokok..............................

这么难以理解?
回复 点赞
kingfish 2005年04月17日
不大明白你的意思,

output.print("ok\r\n");

回复 点赞
foolfish 2005年04月17日
问题就是目前除非我使用
socket.close();或者PrintStream .close()把流或者socket关闭,否则之前print的内容在客户浏览器根本无法显示出来,IE一直是loading的状态.
回复 点赞
whyandwhat 2005年04月17日
回复 点赞
发动态
发帖子
Java SE
创建于2007-09-28

3.4w+

社区成员

30.7w+

社区内容

Java 2 Standard Edition
社区公告
暂无公告