socket循环接收问题

rocrp 2013-10-31 02:35:58
使用socket循环接收报文,调用客户端发送第一次正常接收正常,第二次发送正常接收就把第一发送的一起在累加接收回来了。这是什么原因?大神帮我看看
这是循环接收的工具方法
public static byte[] inceptBigDate(Socket socket) throws Exception{

//包头
byte[] head = new byte[5];
//包体
byte[] body = null;

try {
System.out.println("*********************");
BufferedInputStream in =new BufferedInputStream(
socket.getInputStream());
in.read(head);
int bodyLen = Integer.parseInt(new String(head));

body = new byte[bodyLen];
int tempLen = socket.getReceiveBufferSize();
byte[] temp = null;
int loopIndex=0;
int tempReadLen = 0;
IoBuffer buffer = IoBuffer.allocate(tempLen);
while(true){
temp = new byte[tempLen];
int ind = in.read(temp);
System.arraycopy(temp, 0, body, loopIndex*tempLen, ind);
loopIndex++;
buffer.put(temp);
buffer.flip();
tempReadLen += ind;
if(in.available() <= 0){//Socket数据读完
if(tempReadLen < bodyLen-5){//验证包头中长度与实际收到的长度是否一致
throw new Exception("接收数据有缺失,长度="+(bodyLen-tempReadLen));
}
break;
}
}

} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return body;
}

这是客户端
public class Client {
/**
* 发送报文
*
*/
private Socket socket;

private int msg1_len=100;
private int msg2_len=380;
private String msg1=McisCall.formatString("gd239", msg1_len,0);//
private String msg2=McisCall.formatString("ccc56", msg2_len,0);

MSDate ms=new MSDate("txn121");

public void send() {
try{
socket=new Socket();
socket.connect(new InetSocketAddress("127.0.0.1",8088));

socket.setTcpNoDelay(true);
System.out.println("客户端正在连接...");
byte[] bytes =ms.getDate(msg1+msg2, msg1_len+msg2_len);
String s=new String(bytes);

System.out.println(s+" len "+s.length());
SocketUtil.send(socket, bytes);
System.out.println("发送数据成功");

byte[] res = SocketUtil.accept(socket);//读取服务器端返回bytes
System.out.println("刚读取的:"+res);
String str=new String(res);
System.out.println("Str之后:"+str);
str=ByteOrStringHelper.ByteToString(res,"GBK");
System.out.println("读取服务器返回数据:"+str);
socket.close();
}catch(Exception e){
e.printStackTrace();
}

}
public static void main(String[] args) {
Client demo = new Client();
demo.send();//连接服务器并通信
}

}

这是服务器,出现个客户端就开个线程过去通信的。
public class ServerThread {
private ServerSocket ss;
private int port = 8088;

public ServerThread(){
try {
ss = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}

public void start(){
try {
while(true){
byte[] rec=null;
byte[] msg=null;
System.out.println("等待客户端连接");
Socket socket=ss.accept();
rec=SocketUtil.inceptBigDate(socket);
System.out.println("服务器接受到客户端的连接请求:" + new String(rec));// 用于接收客户端 发来的数据的输入流
//对接收的字符数组进行处理,再发回给客户端

msg=ByteDate.repack(rec);//发送的报文在头部加上报文长度
System.out.println("响应前Length"+msg.length+" 发送的数据:"+new String(msg));
SocketUtil.send(socket, msg);//服务器响应给客户端
System.out.println("响应后");
/*
* 启动一个线程去接待它
*/
Thread clientThread = new Thread(new Handler(socket));
clientThread.start();
}

} catch (Exception e) {
e.printStackTrace();
}
}

/*
* 定义线程体。该线程的作用是与连接到服务器端的客户端进行
* 交互操作。
*/
class Handler implements Runnable{
private Socket socket;
public Handler(Socket socket){
this.socket = socket;
}

public void run(){
try{
//
}catch(Exception e){
e.printStackTrace();
}
}
}

public static void main(String[] args) {
System.out.println("服务器启动中...");
ServerThread demo = new ServerThread();
demo.start();
}
}

这是打印结果:
客户端第一次发送
响应前Length590 发送的数据:00590 txn121
第二次发送
响应前Length1180 发送的数据:00590 txn121
...全文
288 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
rocrp 2013-10-31
  • 打赏
  • 举报
回复
各位大神出出注意吧。搞了一天了
rocrp 2013-10-31
  • 打赏
  • 举报
回复
这是repack的方法。主要就是满足报文接收的需要。包头有个5位描述报文长度的
/**
	 * 对数组重新包装符合socket发送报文条件
	 * @param bytes
	 * @return 报文头为长度的报文
	 */
	public static byte[] repack(byte[] bytes){
		len=bytes.length+5;
		data_len = McisCall.formatString(String.valueOf(len), 5, 3);
		strBuffer.append(data_len.toCharArray());
		strBuffer.append(new String(bytes));
		commBuffer = new byte[strBuffer.length()];//设置返回数组长度
        commBuffer = strBuffer.toString().getBytes();//得到要返回的字符数组
		return commBuffer;
	}
rocrp 2013-10-31
  • 打赏
  • 举报
回复
接收报文头要有报文长度。这是在前面追加了1个报文长度的方法
失落夏天 2013-10-31
  • 打赏
  • 举报
回复
byte[] msg=null; System.out.println("等待客户端连接"); Socket socket=ss.accept(); rec=SocketUtil.inceptBigDate(socket); System.out.println("服务器接受到客户端的连接请求:" + new String(rec));// 用于接收客户端 发来的数据的输入流 //对接收的字符数组进行处理,再发回给客户端 msg=ByteDate.repack(rec);//发送的报文在头部加上报文长度 这里。 这个方法 ByteDate.repack(rec);是对msg进行重写操作还是追加操作?

62,614

社区成员

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

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