还有一个问题,我在外部怎么得知有异常发生???run 函数是 线程类的 特有的,不能抛处异常,也就是说,我用 jsp 来调用的时候, 没法判断是否有异常发生,只有通过 socket.isInputShutdown()socket.isClosed()socket.isConnected()socket.isOutputShutdown()socket.getKeepAlive() socket 这些函数来判断过虑错误发生
有其他好的方法吗?
???????
有其他好的方法吗?
???????
解决方案 »
- sun 公司2006年的一道面试题:下面程序运行结果是多少?
- 关于java applet加载声音的问题
- 用swing编写的桌面程序为什么打包成jar后运行不显示窗体内容
- 高手看一下这段程序,有关于构造方法的重载顺序,不太明白,为什么程序执行出来是A62,而不是62A呢?
- 看Think in JAVA其中有一个例子没明白
- applet问题: 我用IE加载applet时, 老是出现信息栏的警告提示, 请问有什么办法除去信息栏的警告提示呢?
- 多线程从sina网采集股票实时数据
- java.sql.Date构件器的问题
- 子线程如何将运算结果返回给调用方
- awt 中FileDialog导致死机问题
- 帮我看看,这个java那里错误
- ¥¥¥¥vj6中有“dheventhandle”这个东西吗?¥¥¥¥(初学者)
像你使用的这种情况,那几个输出肯定是要等write或flush完成以后才会执行的,按理说若无返回值,传输失败的话就会报异常的说
btw:JSP调试,若使用Jbuilder的话,你可以将异常在后台输出阿,也同样可以看到的
我很久没做socket这些东西了,手头上现在也没资料,不知道如上所说对你是否有帮助
2.另外对方给出的数据结构 是 byte[] ,于是好像只查到
protected InputStream in = null;
protected OutputStream out = null;
能够实现
3. 在vc 的CSocket 中的 send 倒是可以返回一个值来判断发送是否正确,
但java中就是没找到这种类似的方法。只有从异常来判断 :(((
4. 还有关于 KeepAlive 的问题,因为是java 对接 c 的socket, 要是c 判断连接断开了,而java认为还连接着,发送时候 是否会抛出异常。
?????
请高手指点!!!!
我清清楚楚记得我1年前做过一个socket通讯的,对方是VC,我当时用以接受数据的流是可以返回一个long类型判断是否传输成功,难道是接受时才有的?我都忘了
郁闷的问题,根本没发调试!!!!可以说明write已经完成了,如果在write的过程中出现错误,就会有IOException抛出,你可以在这里面进行一些关闭连接的操作。
但对方说没收到,又没在一个地方,只有听对方说没收到我怀疑是socket 断了,当java 就是不出现异常, write 函数也没有返回值
=======================
package com.softwife;import java.io.*;
import java.net.*;
import java.util.*;public class Connection { protected Socket socket = null;
ReadThread readThread = new ReadThread();
WriteThread writeThread = new WriteThread();
protected InputStream in = null;
protected OutputStream out = null;
public static final int PING_TIME = 10 * 1000;
public static final boolean verboseMode = true; public Connection(Socket asocket) {
socket = asocket;
}
public void send(Object obj) {
send(obj.toString());
}
public void send(byte s[]) {
System.out.println(new String(s));
writeThread.send(s);
}
/**
* attempts to connect and perform any handshaking required to establish communications.
*/
public boolean connect() {
try {
// experimental
//socket.setSoTimeout(PING_TIME); in = socket.getInputStream();
out = socket.getOutputStream();
if (!handshake()) throw new IOException("Faking this");
} catch (IOException e) {
closeSocket();
return false;
}
return true;
}
/**
* starts the asynchronous read/write threads.
* call this after connect()
*/
public void start() {
readThread.start();
writeThread.start();
}
/**
* perform any handshaking required. in/out have already been setup.
* return false to abort.
* override in descendants
*/
public boolean handshake() throws java.io.IOException {
return true;
}
/**
* override in descendants
*/
public void onRead(byte s[]) { }
/**
* override in descendants
*/
public void onClose() { }
public synchronized void closeSocket() {
try {
System.out.println(socket.isInputShutdown()+"== isClosed="+socket.isClosed()+" ==isConnected="+socket.isConnected()+" ==isInputShutdown"+socket.isOutputShutdown()+" ==getKeepAlive="+socket.getKeepAlive() );
socket.close();
} catch (IOException e) { }
}
private class ReadThread extends Thread {
public void run() {
byte[] buf = new byte[1024];
int i=0;
while(true) {
//if(++i>100) break;
int iLength = 0;
byte len[] = new byte[4]; //这组数据的长度
try {
if ( in.read( len, 0,4 ) != -1 ){
iLength = ((int)len[0]) | (((int)len[1])<<8) | (((int)len[2])<<16) | (((int)len[3])<<24) ;
if(in.read(buf, 0, iLength-4) != -1){
onRead(buf);
}
}
} catch (IOException e) {
System.out.println("readTheadClose");
closeSocket();
break;
}
}
onClose();
}} // of ReadThreadprivate class WriteThread extends Thread {
Vector outBuffer = new Vector();
public synchronized void send(byte s[]) {
outBuffer.addElement(s);
notifyAll();
} public void run() {
try {
while (true) {
byte[] s = getNextSendObject();
if (s == null) {
// out.write((byte)0); out.flush();
} else {
int len = ((int)s[0]) | (((int)s[1])<<8) | (((int)s[2])<<16) | (((int)s[3])<<24) ;
for(int i=0;i<len;i++) System.out.print(s[i]);
System.out.println(socket.isInputShutdown()+"==okokoisClosed="+socket.isClosed()+" ==isConnected="+socket.isConnected()+" ==isInputShutdown"+socket.isOutputShutdown()+" ==getKeepAlive="+socket.getKeepAlive() );
out.write(s,0,len); out.flush();
System.out.print("ok");
}
}
} catch (IOException e) {
e.printStackTrace();
closeSocket();
} catch (Exception ep) {
ep.printStackTrace();
closeSocket();
}
} private synchronized byte[] getNextSendObject() {
if (outBuffer.size() == 0) {
try { wait(PING_TIME); } catch (InterruptedException e) { }
}
// if still empty, return null
if (outBuffer.size() == 0) return null; Object obj = outBuffer.elementAt(0);
outBuffer.removeElementAt(0);
return (byte[])obj;
}
} // of WriteThread}
================================
package com.softwife.sms;
import com.softwife.*;
import java.net.*;
import java.util.*;
import java.text.*;
import sun.io.*;public class SMSManager {
private static Object initLock = new Object();
private static String className = "com.softwife.sms.SMSManager";
private static SMSManager manager = null;
private static SMSConnection connection = null; public static SMSManager getInstance() {
if (manager == null) {
synchronized(initLock) {
if (manager == null) {
try {
Class c = Class.forName(className);
manager = (SMSManager)c.newInstance();
}
catch (Exception e) {
System.err.println("不能装载类 " + className );
e.printStackTrace();
return null;
}
}
}
} return manager;
}
private SMSManager(){
try {
Socket socket = new Socket(getHost(), getBasePort());
socket.setKeepAlive(true);
connection = new SMSConnection(this, socket);
} catch (Exception e) {
e.printStackTrace();
System.out.println("不能连接到这个端口");
return;
} if (!connection.connect()) {
System.out.println("Rejected: Try again");
return;
}
connection.start();
login();
}
private String getHost(){ return "www.softwife.com"; }
private int getBasePort(){ return 7760; } private synchronized void login()
{
String SPName = "softwife", SPPassword="softwife", SPType="sp";
byte pData[] = new byte[1024]; int iCount = 0 , i;
int iCommandID = 0x1;
byte command[] = new byte[4];
command[3] = (byte)( (iCommandID & 0xff000000) >>> 24);
command[2] = (byte)( (iCommandID & 0x00ff0000) >>> 16);
command[1] = (byte)( (iCommandID & 0x0000ff00) >>> 8);
command[0] = (byte)( (iCommandID & 0x000000ff) );
byte name[] = SPName.getBytes();
int nameLen = SPName.length() + 1 ;
byte password[] = SPPassword.getBytes();
int passwordLen = SPPassword.length() + 1;
byte type[] = SPType.getBytes();
int typeLen = SPType.length() + 1;
iCount = 4*2 + nameLen + passwordLen + typeLen;
byte len[] = new byte[4];
len[3] = (byte)( (iCount & 0xff000000) >>> 24);
len[2] = (byte)( (iCount & 0x00ff0000) >>> 16);
len[1] = (byte)( (iCount & 0x0000ff00) >>> 8);
len[0] = (byte)( (iCount & 0x000000ff) ); //数据的长度
for(i=0; i<4; i++){
pData[i] = len[i];
}
//指令代码
for(i=0; i<4; i++){
pData[i+4] = command[i];
}
//账号
for(i=0; i<nameLen-1; i++){
pData[i+8] = name[i];
}
pData[8+nameLen-1] = 0;
//密码
for(i=0; i<passwordLen-1; i++){
pData[i+8+nameLen] = password[i];
}
pData[8+nameLen+passwordLen-1] = 0;
//类型
for(i=0; i<typeLen-1; i++){
pData[i+8+nameLen+passwordLen] = type[i];
}
pData[8+nameLen+passwordLen+typeLen-1] = 0;
//for(i=0; i<iCount; i++) System.out.print("_"+pData[i]);
connection.send(pData);
}
public synchronized void send(String strSource, String strDest, String strMessage, int freeTyep, int freeValue)
throws Exception
{
try{
byte pData[] = new byte[1024]; int iCount = 0 , i;
int iCommandID = 0x2;
//指令
byte command[] = new byte[4];
command[3] = (byte)( (iCommandID & 0xff000000) >>> 24);
command[2] = (byte)( (iCommandID & 0x00ff0000) >>> 16);
command[1] = (byte)( (iCommandID & 0x0000ff00) >>> 8);
command[0] = (byte)( (iCommandID & 0x000000ff) );
//付费类型
byte type[] = new byte[4];
type[3] = (byte)( (freeTyep & 0xff000000) >>> 24);
type[2] = (byte)( (freeTyep & 0x00ff0000) >>> 16);
type[1] = (byte)( (freeTyep & 0x0000ff00) >>> 8);
type[0] = (byte)( (freeTyep & 0x000000ff) );
//付费数量
byte value[] = new byte[4];
value[3] = (byte)( (freeValue & 0xff000000) >>> 24);
value[2] = (byte)( (freeValue & 0x00ff0000) >>> 16);
value[1] = (byte)( (freeValue & 0x0000ff00) >>> 8);
value[0] = (byte)( (freeValue & 0x000000ff) );
//源号码
byte source[] = strSource.getBytes();
int sourceLen = source.length + 1;
//目的号码
byte dest[] = strDest.getBytes();
int destLen = dest.length + 1;
//短信内容
byte[] msg = strMessage.getBytes();
int msgLen = msg.length + 1;
//数据流的长度
iCount = 4*4 + sourceLen + destLen + msgLen;
byte len[] = new byte[4];
len[3] = (byte)( (iCount & 0xff000000) >>> 24);
len[2] = (byte)( (iCount & 0x00ff0000) >>> 16);
len[1] = (byte)( (iCount & 0x0000ff00) >>> 8);
len[0] = (byte)( (iCount & 0x000000ff) );
for(i=0; i<4; i++){
pData[i] = len[i];
}
for(i=0; i<4; i++){
pData[i+4] = command[i];
}
for(i=0; i<4; i++){
pData[i+8] = type[i];
}
for(i=0; i<4; i++){
pData[i+12] = value[i];
} for(i=0; i<sourceLen-1; i++){
pData[i+16] = source[i];
}
pData[16+sourceLen-1] = 0; for(i=0; i<destLen-1; i++){
pData[i+16+sourceLen] = dest[i];
}
pData[16+sourceLen+destLen-1] = 0; for(i=0; i<msgLen-1; i++){
pData[i+16+sourceLen+destLen] = msg[i];
}
pData[16+sourceLen+destLen+msgLen-1] = 0; connection.send(pData);
} catch(Throwable e) {
e.printStackTrace();
throw new Exception("发送短信时出现错误!");
}
} public synchronized void handleCommand(byte cmd[])
{
try {
int iCommandID = 0, i;
byte command[] = new byte[4]; //指令 for(i=0; i<4; i++) command[i] = cmd[i];
iCommandID = ((int)command[0]) | (((int)command[1])<<8) | (((int)command[2])<<16) | (((int)command[3])<<24) ;
byte ok[] = new byte[4];
switch( iCommandID ){
case 0x80000001: //登陆成功
int loginOK;
for(i=0; i<4; i++) ok[i] = cmd[i+4];
loginOK = ((int)ok[0]) | (((int)ok[1])<<8) | (((int)ok[2])<<16) | (((int)ok[3])<<24) ;
if( loginOK >0 ) System.out.println("^_^,登陆成功!");
break;
case 0x80000002: //回应短消息格式
int sendOK;
for(i=0; i<4; i++) ok[i] = cmd[i+4];
sendOK = ((int)ok[0]) | (((int)ok[1])<<8) | (((int)ok[2])<<16) | (((int)ok[3])<<24) ;
//if( sendOK >0 ) System.out.println("^_^,发送成功!");
System.out.println("^_^,发送成功!NO="+sendOK); break;
case 0x3: //接收短信
String sourceNO , destNO , message ;
byte srcByte[] = new byte[30], destByte[] = new byte[30], msgByte[] = new byte[300];
i=0;
while(cmd[i+4] != 0) { srcByte[i] = cmd[i+4]; i++; }
i++;
while(cmd[i+4] != 0) { destByte[i] = cmd[i+4]; i++; }
i++;
while(cmd[i+4] != 0) { msgByte[i] = cmd[i+4]; i++; }
sourceNO = new String(srcByte);
destNO = new String(destByte);
message = new String(msgByte);
System.out.println("sourceNO="+sourceNO+" destNO="+destNO+" message="+message);
break;
default:
System.out.println("sourceNO 错 !!!!");
//throw new RuntimeException("Don't know how to handle this"); } } catch (Exception e) {
e.printStackTrace();
System.err.println("错误的数据!");
return;
}
} public void shutdown() {
connection.closeSocket();
}
}
write方法也没有判断是否写结束的方法,你可以用java专门写一个server的接受程序,看它到底有没有收到数据.
read方法中虽然能够得到读入的字节数来判断有没有结束,但如碰到timeout就没办法了。
我在写java的http的通信问题时也碰到不少的问题,大家可以多交流一下,感觉用java写socket通信的人不是很多。 My Email:[email protected]