需求如下:
客户端   :向服务器端发送信息,并接收服务器端的反馈信息.
服务器端 :接收客户端发来的信息并反馈信息给客户端.
实现如下 :
import java.io.*;
import java.net.*;
import java.util.*;public class Tcp{ public void yReceiverSend(int port)
    {
ServerSocket serveSocket    = null;
Socket clientSocket         = null;
BufferedInputStream input   = null;
InputStream inputStream     = null;
OutputStream outputStream   = null;
byte[] buffer = new byte[1024];                                                    //平台生成的XML串
        ByteArrayOutputStream streamXML = new ByteArrayOutputStream();                   //请求数据存放对象 try{
serveSocket = new ServerSocket(port);                                           //在指定端口建立一个连接
System.out.println("开始监听:");

while (true){
clientSocket = serveSocket.accept();                                         //收到一个信息,得到一个clientSocket
clientSocket.setSoTimeout(5000);
inputStream = clientSocket.getInputStream();                                 //数据缓冲区
            int count = 0;                                                           //每个缓冲区的实际数据长度
            try {
     input = new BufferedInputStream(inputStream);
     while ((count = input.read(buffer)) != -1){
     streamXML.write(buffer, 0, count);
     }
     }catch (Exception e){
     e.printStackTrace();
     }      System.out.println("收到客户端发来的如下信息:  " + streamXML.toString());
     streamXML.reset();
     outputStream = clientSocket.getOutputStream();
     buffer = "我是服务器,你的请求已经收到!".getBytes();                           //反馈信息
         outputStream.write(buffer);
         outputStream.flush();
         outputStream.close();
         inputStream.close();
}
}catch (Exception e){
e.printStackTrace();
}
    }

public void send(String host,int port){
    InputStream inputStream = null;
byte[] buffer = new byte[1024];
try{
Socket socket = new Socket("192.168.61.146",20000);
socket.setSoTimeout(0);
OutputStream outputStream = socket.getOutputStream();
BufferedInputStream input = null;
        ByteArrayOutputStream streamXML = new ByteArrayOutputStream();
buffer = "abcdefghijklmnopqrstuvwxyz".getBytes();                    //要发给服务器端的信息
outputStream.write(buffer);
outputStream.flush();
System.out.println("发送数据完毕!!!");//---------------------------------------------------------------------------
//接收服务器端的反馈
buffer = "".getBytes();
inputStream = socket.getInputStream(); int count = 0;
try {
input = new BufferedInputStream(inputStream);
while ((count = input.read(buffer)) != -1){//到这里就有问题了
streamXML.write(buffer, 0, count);
}
}catch (Exception e){
e.printStackTrace();
}finally{
if (input != null){
try {
input.close();
}catch (Exception f){
f.printStackTrace();
}
}
}
//----------------------------------------------------------------------------
System.out.println("收到服务器的如下反馈:" + streamXML.toString());
         inputStream.close();
outputStream.close();
socket.close();
streamXML.reset();
}catch (Exception e){
e.printStackTrace();
}
}
}
问题如下:
如果客户端只发送信息而不接收服务器的反馈时,程序执行正常.
如果接收反馈时,收不到反馈,在我标注的地方就定住了.哪位高手能解决我的这个需求哦~我一定会好好感谢.
大家也可以给出建议,最好能把解决的代码给我.谢谢了 .
分不够再加100.

解决方案 »

  1.   

    DataInputStream 用这个流 把BufferedInputStream 换成这就好了
      

  2.   

    BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream())); 全改成:DataInputStream in = new DataInputStream(inStr);
    BufferedWriter bWriter=new BufferedWriter(new OutputStreamWriter( socket.getOutputStream())); 全改成:DataOutputStream bWriter = new DataOutputStream(
    socket.getOutputStream());
    读写方法用readUTF();writeUTF();原因是因为频繁使用readLine()方法,因此必须在发消息的时候加上"\r\n",否则该方法会阻塞.不行就用上面的方法
      

  3.   

    问题找到了firstly:
    to liufei8463(武汉小兵)
    你的理解错误的
    BufferedInputStream实际上是对InputStream实现缓冲封装,这样可以提高效率。所以不但不可以不用,反而要多用才好。DataInputStream只不过对InputStream简单封装一下,解决了一些基本数据转换的问题,没有什么太大的变化,尤其对byte数组读写。
    用BufferedReader也不可取,这个是对字符流做读写的,不是对字节流。lz的读写虽然是针对String的,但用BufferedReader来代替在其他情况下就会出问题。readUTF对于其他语言的tcp接口不支持,少用为好
    lz的问题是buffer = "".getBytes();
    你把buffer设置成了一个byte数组,但长度是0。为什么这样做呢?直接buffer=new byte[4096]不就可以了吗。费了好大的力气才找出来,汗
      

  4.   

    是不是啊.那楼上的请你看看这个问题是什么
    http://community.csdn.net/Expert/topic/5165/5165981.xml?temp=.1623194
      

  5.   

    buffer=new byte[4096] 我原来是这样的,还是不行 问题是不能接收到服务端返回的数据!高手快来哦!
    liufei8463(武汉小兵) 
    你写的代码不是我程序里的呀!
      

  6.   

    buffer = "".getBytes();
    这个是什么阿?
      

  7.   

    在线等!请大家帮忙认真看看,如果成功了.就是一个典型得TCP通信得例子了.以后 可以用!
      

  8.   

    to lz:
    你的代码真的还需要好好琢磨一下。比较乱。这个只能是让你知道Stream的用法,典型得TCP通信得例子还是别的好我3楼的说法你要看看,这样来实现缓冲是不可以的,必须要buffer=new byte[4096]的形式。至于liufei8463(武汉小兵) 的说法我不苟同。他贴的那个帖子我也有点异议,不过已经结的就不说了。
    拟定问题出在while ( (count = input.read(buffer)) != -1) 这句话
    InputStream读取数据,当read的数据量大于0的时候返回读取字节数,当遇到结尾的时候返回-1。这个说法不确切。
    实际上只有InputStream的public int read()方法才是完全这样的。它会一个字节一个字节的读取,当读到流末尾的时候会返回-1。而public int read(byte b[], int off, int len)并不是这样。这个方法只有当读取的第一个字节就是流末尾时才会返回-1。
    举个例子:
    socket传输数据包,长度1000个字节
    如果我们buffer=new byte[1024];
    第一次input.read(buffer)返回1000,但第二次read的时候并不是返回-1;而是在这里等待.因为上次读取时流已经到末尾了.
    一般在做流输出的时候都要加上自己的包头,用来描述包的长度.
    如在发送buffer之前先发送一个int数据或者一个固定长度的string,接收也一样,解析后得到总长度,然后按照这个长度去接收剩余的数据.
      

  9.   

    必须是4096吗?我定的是1024.
    这个确实是个问题,我原来不是buffer = "".getBytes();这么写的.就是new byte[1024]现在就是客户端建立一个socket 用它来发送信息. 服务器端已经能收到了.
    (我用//---------------标记的部分注释掉,程序运行正常.)但是把//--------这部分加到程序里就不行了!
    但是服务器端返回的信息客户端不能收到.
    谢谢大家了 呵呵!尤其谢谢!fool_leave(请及时结贴)
      

  10.   

    我只给你简单的代码,具体的自己想一下,也不难//先准备流,注意,这里的流在发送和接收两个程序里都创建
    InputStream is;
    OutputStream os;
    //大量数据传输最好用Buffered流
    BufferedInputStream bis=new BufferedInputStream(is);
    BufferedOutputStream bos=new BufferedOutputStream(os);
    假设每次读取1个String,都发送0x01返回给对方,表示成功
    发送数据部分://准备字符串发送
    String data="aaaaaaaaaaaaa";
    byte buf[]=data.getBytes();
    //准备数据头
    byte headbuf[]=new byte[4];
    String head=String.valueOf(buf.length);
    System.arraycopy(head.getBytes(),0,headbuf,0,4);
    //这里我采用String作为头只是为了方便和其他语言的tcp链接,不然需要高低位转换
    //你也可以自己去设计头
    //net 工作
    bos.write(headbuf);
    bos.write(buf);
    bos.flush();
    int res=bis.read();
    if(res!=0x01){
       System.out.println("err");
    }
    接收部分:
    //一样准备头缓存
    byte headbuf[]=new byte[4];
    //接收头
    bis.read(headbuf);
    String head=new String(headbuf).trim();
    //得到数据长度
    int len=Integer.parseInt(head);
    //创建数据buffer
    byte buf[]=new byte[len];
    //读取数据
    bis.read(buf);
    //回执
    bos.write(0x01);
    bos.flush();我没有调试,应该有拼写错误
    重要的是思路
    对于头部分每个人的习惯不同,你可以自己设计头数据
    这里没有捕捉错误,也没有考虑异常,你自己写代码时别忘了怎么样,满意否?汗,现在在csdn上积分真不易呀