主要线程部分:import java.net.*;import java.io.*;import java.util.*;public class sendMsg extends Thread{Socket sok_cm=null;Vector vct_svrtocm=null;DataOutputStream dos_svrtocm=null;int int_sleeptime;public boolean b_stop=false;public sendMsg(Socket sok_cm,Vector vct_svrtocm,int int_sleeptime){
this.sok_cm=sok_cm;
this.vct_svrtocm=vct_svrtocm;
this.int_sleeptime=int_sleeptime;
}
private void openOS(){
try{
//sok_cm.setKeepAlive(true);
dos_svrtocm=new DataOutputStream(sok_cm.getOutputStream());
}
catch(IOException ioe){System.out.println("建立输出流出现异常:"+ioe.toString());}
//catch(SocketException se){System.out.println("KeepAlive:"+se.toString());}
}
private void sendtocm(){
synchronized(vct_svrtocm){
if (!vct_svrtocm.isEmpty()){ int n=vct_svrtocm.size();
System.out.println(n);
try{
//System.out.println(sok_cm.getSendBufferSize());
/**
System.out.println("old title:"+dos_svrtocm.size());
for(int i=0;i<n;i++){
byte[] bya_temp=(byte[])vct_svrtocm.elementAt(i);
try{
dos_svrtocm.write(bya_temp,0,bya_temp.length);
System.out.println("send:"+i+" "+bya_temp.length );
}
catch(IOException ioe){System.out.println("dos.write:"+ioe.toString());}
}
*/
//一次只发送一条
System.out.println("old title:"+dos_svrtocm.size());
dos_svrtocm.write((byte[])vct_svrtocm.firstElement());
System.out.println("new title:"+dos_svrtocm.size());
dos_svrtocm.flush();
System.out.println("flush");
vct_svrtocm.removeElementAt(0);
}
catch(Exception e){System.out.println("chat_sendmsg"+e.toString());
e.printStackTrace();
b_stop=true;
}
}
}//end of synchronized
}
public void run(){
openOS();
while(true){
if(!b_stop){
sendtocm();
//System.out.println("**********sendtocm正在活动**********");
try{
Thread.sleep(int_sleeptime);
}
catch(InterruptedException ie){}
}
else{
try{
if (dos_svrtocm!=null){
dos_svrtocm.close();
dos_svrtocm=null;
//System.out.println("sendMsg关闭了输出流");
}
}
catch(IOException ioe){}
finally{break;} }
}System.out.println("消灭tcmc.chat.thread.sendMsg线程");
}
}
我认为是很标准的发送方法,到写到一定的字节数(并不确定写了多少),一执行到到了dos_svrtocm.write();就没有相应了。也没有异常抛出。
this.sok_cm=sok_cm;
this.vct_svrtocm=vct_svrtocm;
this.int_sleeptime=int_sleeptime;
}
private void openOS(){
try{
//sok_cm.setKeepAlive(true);
dos_svrtocm=new DataOutputStream(sok_cm.getOutputStream());
}
catch(IOException ioe){System.out.println("建立输出流出现异常:"+ioe.toString());}
//catch(SocketException se){System.out.println("KeepAlive:"+se.toString());}
}
private void sendtocm(){
synchronized(vct_svrtocm){
if (!vct_svrtocm.isEmpty()){ int n=vct_svrtocm.size();
System.out.println(n);
try{
//System.out.println(sok_cm.getSendBufferSize());
/**
System.out.println("old title:"+dos_svrtocm.size());
for(int i=0;i<n;i++){
byte[] bya_temp=(byte[])vct_svrtocm.elementAt(i);
try{
dos_svrtocm.write(bya_temp,0,bya_temp.length);
System.out.println("send:"+i+" "+bya_temp.length );
}
catch(IOException ioe){System.out.println("dos.write:"+ioe.toString());}
}
*/
//一次只发送一条
System.out.println("old title:"+dos_svrtocm.size());
dos_svrtocm.write((byte[])vct_svrtocm.firstElement());
System.out.println("new title:"+dos_svrtocm.size());
dos_svrtocm.flush();
System.out.println("flush");
vct_svrtocm.removeElementAt(0);
}
catch(Exception e){System.out.println("chat_sendmsg"+e.toString());
e.printStackTrace();
b_stop=true;
}
}
}//end of synchronized
}
public void run(){
openOS();
while(true){
if(!b_stop){
sendtocm();
//System.out.println("**********sendtocm正在活动**********");
try{
Thread.sleep(int_sleeptime);
}
catch(InterruptedException ie){}
}
else{
try{
if (dos_svrtocm!=null){
dos_svrtocm.close();
dos_svrtocm=null;
//System.out.println("sendMsg关闭了输出流");
}
}
catch(IOException ioe){}
finally{break;} }
}System.out.println("消灭tcmc.chat.thread.sendMsg线程");
}
}
我认为是很标准的发送方法,到写到一定的字节数(并不确定写了多少),一执行到到了dos_svrtocm.write();就没有相应了。也没有异常抛出。
DataOutputStream在write()一定的字节数组后,就好像阻塞了一样,停在write()方法出不动了。我原来把收发消息做在了两个Thread里,现在有把他们都放在一个Thread里,还是由此现象。怎么回事?急切!!
还有就是flush()方法不是把现在流里的数据发送出去吗?flush()以后,流就空了。这时候数据应该到了ISO的更底层了,交给网卡去打包了,数据会不会堵在了网卡?我也不是太明白。看在我努力思考的分上,高手帮帮我!
我把收发消息现在做在了一个线程里面,在一个循环中:先向VC服务器发送数据,然后再用DataInputStream.read(byte[] b)数据,但是VC服务器并不是一定会给我发返回数据的,在协议中就是这么定的,所以设置sotime时间,超时后返回。我在测试的时候,正如您所说的确只是发送了数据,VC服务器并没有返回信息,但是我不太明白的是:照此道理一个套接字连接必须要实现数据的发和收才可以吗?我要是在应用中,只需要它的发数据功能怎么办?非给每一次发送后,在接受一个返回消息吗?再有Socket.shutdownOutput()和Socket.shutdownInput()这两个方法不就是可以关闭一个方向的流吗?如此要时关闭了一个方向的流,Socket也就完蛋了?
真是让人感到奇怪呀!再次感谢,也许看到希望了。
上面您说的是不是要实现read()方法,即使read()不到数据,产生InterruptedException后返回?我就是这么写得呀?
这种情况和网络环境有没有关系?我的网卡是10mb局域网,VC服务器是局域网的另一台机器。
痛苦呀!~~~~
给我一个Email地址,我把修正程序代码和辅助测试的程序代码给你发过去。
[email protected]
我要学习一下,必有重谢!
[email protected]
我要学习一下,必有重谢!
只要与VC服务器通信,VC即便发返回消息,java端也是会被阻塞的。但是这是在局域网环境下的测试,java版本的测试是在一台机器上,数据其实并没有出去。和这个有没有关系?还请大家多多帮助!!
再次感谢lizicai,必有重分向谢!!
还有就是缓冲区如何请空?flush()以后不就请空了吗?不知道理解的对不对,那又是如何被填满溢出的呢?
我的程序中还有那些地方不完善,请Sir lizicai指正出来,我好学习一下。
再次感谢Sir Lizicai。