导航
  • 全部
...

难道还有第3条分支???怎么判断 socket 的数据已经传输

天限天空 2002-11-21 09:40:59
try {
while (true) {
byte[] s = getNextSendObject();
if (s == null) {
} 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();
System.out.println("okokokokokoo!!!!!!!!!!!!!!");
}

如果打印出了 for(int i=0;i<len;i++) System.out.print(s[i]); 和 System.out.print("ok"); 没有打印出e.printStackTrace();,ep.printStackTrace(); 能够说明 out.write(s,0,len); out.flush(); 已经完成吗????
郁闷的问题,根本没发调试!!!!


...全文
给本帖投票
724 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
Arbinsun 2002-11-24
  • 打赏
  • 举报
回复
java中好多对socket的操作都是用异常来判断的,如read方法的Timeout,感觉到它将Exception当作一种正常的处理机制了。
write方法也没有判断是否写结束的方法,你可以用java专门写一个server的接受程序,看它到底有没有收到数据.
read方法中虽然能够得到读入的字节数来判断有没有结束,但如碰到timeout就没办法了。
我在写java的http的通信问题时也碰到不少的问题,大家可以多交流一下,感觉用java写socket通信的人不是很多。

My Email:liyh@neusoft.com
chen_2001 2002-11-21
  • 打赏
  • 举报
回复
up
天限天空 2002-11-21
  • 打赏
  • 举报
回复
1.首先我查了 DataInputStream 的write 方法 返回值是 void
2.另外对方给出的数据结构 是 byte[] ,于是好像只查到
protected InputStream in = null;
protected OutputStream out = null;
能够实现
3. 在vc 的CSocket 中的 send 倒是可以返回一个值来判断发送是否正确,
但java中就是没找到这种类似的方法。只有从异常来判断 :(((
4. 还有关于 KeepAlive 的问题,因为是java 对接 c 的socket, 要是c 判断连接断开了,而java认为还连接着,发送时候 是否会抛出异常。
?????
请高手指点!!!!
alphazhao 2002-11-21
  • 打赏
  • 举报
回复
socket传输是否结束,我记得传输数据流数据的DataInputStream(应该是这个类名吧?)类的write方法传输完后会返回一个int值,从而判断是否传输成功,同样,对应DataOutputStream其read方法则可以返回一个long值,是接收到的数据流byte[]的长度,好像为-1则传输失败
像你使用的这种情况,那几个输出肯定是要等write或flush完成以后才会执行的,按理说若无返回值,传输失败的话就会报异常的说
btw:JSP调试,若使用Jbuilder的话,你可以将异常在后台输出阿,也同样可以看到的
我很久没做socket这些东西了,手头上现在也没资料,不知道如上所说对你是否有帮助
天限天空 2002-11-21
  • 打赏
  • 举报
回复
还有一个问题,我在外部怎么得知有异常发生???

run 函数是 线程类的 特有的,不能抛处异常,也就是说,我用 jsp 来调用的时候, 没法判断是否有异常发生,只有通过 socket.isInputShutdown()socket.isClosed()socket.isConnected()socket.isOutputShutdown()socket.getKeepAlive() socket 这些函数来判断过虑错误发生
有其他好的方法吗?
???????
天限天空 2002-11-21
  • 打赏
  • 举报
回复
下面是是一个 短信管理类
================================
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();
}
}
天限天空 2002-11-21
  • 打赏
  • 举报
回复
我把代码贴出来:请大家看看 到底是那里出错了

连接类
=======================
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 ReadThread

private 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

}
天限天空 2002-11-21
  • 打赏
  • 举报
回复
我是在对接一个别人的socket 端口, 按照上面的分析,已经发送了数据,
但对方说没收到,又没在一个地方,只有听对方说没收到

我怀疑是socket 断了,当java 就是不出现异常, write 函数也没有返回值
ggzzkk 2002-11-21
  • 打赏
  • 举报
回复
如果真的想调试有异常的情况,你可以加上Thread.sleep(5000);等待5秒,然后马上把服务器关掉,这样write就有IOException
ggzzkk 2002-11-21
  • 打赏
  • 举报
回复
如果打印出了 for(int i=0;i<len;i++) System.out.print(s[i]); 和 System.out.print("ok"); 没有打印出e.printStackTrace();,ep.printStackTrace(); 能够说明 out.write(s,0,len); out.flush(); 已经完成吗????
郁闷的问题,根本没发调试!!!!

可以说明write已经完成了,如果在write的过程中出现错误,就会有IOException抛出,你可以在这里面进行一些关闭连接的操作。
fastmask 2002-11-21
  • 打赏
  • 举报
回复
socket的写操作缺省是阻塞方式的,你调用write返回,就证明已经发送完成(当然有异常就是发送 失败了)。
天限天空 2002-11-21
  • 打赏
  • 举报
回复
请具体点
好吗?
ggzzkk 2002-11-21
  • 打赏
  • 举报
回复
socket write时外界只有在异常中抛出应用级异常
天限天空 2002-11-21
  • 打赏
  • 举报
回复
的确没找到!
连调试的方法都没有!!!
alphazhao 2002-11-21
  • 打赏
  • 举报
回复
不可能阿
我清清楚楚记得我1年前做过一个socket通讯的,对方是VC,我当时用以接受数据的流是可以返回一个long类型判断是否传输成功,难道是接受时才有的?我都忘了

62,636

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧

手机看
关注公众号

关注公众号

客服 返回
顶部