0 0

JAVA sockets read()接收数据超时阻塞的解决方法5

遇到一个问题,用JAVA和Delphi写的服务端进行sockets交互。
当服务端返回给我一条String型字符串时,我能正常接收到(即使网络有延迟时,过一会仍然能接收到)。但当服务端不定时返回给我多条String型字符串时,我却一条都接收不到,一直阻塞中。代码如下:
private String ReadSocketsText(Socket socket){
   try
    socket.setSoTimeout(sotimeout);
    InputStream input = socket.getInputStream();
    BufferedReader in = new BufferedReader(new InputStreamReader(input));
    char[] sn = new char[1000];
    //read()会在这里阻塞。
    in.read(sn);
    String sc = new String(sn);
    return sc;
   }catch(IOException se){
   se.printStackTrace();
    return null;
   }
}
我查了下资料,read()是阻塞制的,当接收不到数据时会一直等待。但服务端虽然有延迟发送,但当服务端已经把String数据返回时,read()仍然处于阻塞中,没有收到任何一条数据。这是何解?该怎么解决。。。这个问题困惑我已经几个月了,到现在了仍然是没有解决方法。。
网上查了很多资料,试用了很多很多的方法,仍然解决不了。有人说用NIO的netty框架,但苦于不会使用。。。我只是想解决这么个问题,难道就这么难么??
2014年1月19日 21:00

2个答案 按时间排序 按投票排序

0 0

想我当年还用socket写过聊天室,这应该是不定时的吧。
public class SocketManager { 
    /**
     * @param args
     * @throws IOException 
     */ 
    public static void main(String[] args) { 
        SocketManager manager = new SocketManager(); 
       manager.doListen(); 
    } 

    public void doListen() { 
        ServerSocket server; 
       try { 
            server = new ServerSocket(9991); 
            while (true) { 
                Socket client = server.accept(); 
                new Thread(new SSocket(client)).start(); 
            } 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } 
 
    } 

    //服务器进程 
    class SSocket implements Runnable { 

        Socket client; 

        public SSocket(Socket client) { 
            this.client = client; 
        } 

        public void run() { 
           DataInputStream input; 
            DataOutputStream output; 
            try { 
                input = new DataInputStream(client.getInputStream()); 
                output = new DataOutputStream(client.getOutputStream()); 
// 
                String listMsg = input.readUTF(); 
                output.writeUTF("Recive:  " + listMsg + "    \r\n Thx..."); 
               System.out.println("Recive:   " + listMsg); 
                listMsg = input.readUTF(); 
                output.writeUTF("Recive Second:  " + listMsg + "    \r\n Thx..."); 
                System.out.println("Recive Second:   " + listMsg); 
            } catch (IOException e) { 
                e.printStackTrace(); 
            } 
        } 
    } 
 
}

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class SocketClient {
public static void main(String[] args) { 
         Socket socket = null; 
        try { 
             socket = new Socket("127.0.0.1", 9991); 
            //向服务器端第一次发送字符串    
            OutputStream netOut = socket.getOutputStream(); 
            DataOutputStream doc = new DataOutputStream(netOut); 
             DataInputStream in = new DataInputStream(socket.getInputStream()); 
            //向服务器端第二次发送字符串    
            doc.writeUTF("list"); 
            String res = in.readUTF(); 
             System.out.println(res); 
             doc.writeUTF("bye"); 
             res = in.readUTF(); 
            System.out.println(res); 
             doc.close(); 
             in.close(); 
         } catch (UnknownHostException e) { 
             e.printStackTrace(); 
         } catch (IOException e) { 
            e.printStackTrace(); 
         } finally { 
             if (socket != null) { 
                try { 
                     socket.close(); 
                 } catch (IOException e) { 
                } 
             } 
        } 
     }

}

你看这个,你任意启动client,server总能读到数据。

2014年1月20日 09:51
0 0

应该是BufferedReader导致的,BufferedReader默认内部有缓冲区,size为8192,你应用层只有1000个字符,应该不满没有返回。可以将BufferedReader去掉试一下。另外,可以使用一下网络抓包工具查看一下是否有数据包传输。

2014年1月20日 09:19

相关推荐

    C#局域网内发送和接收数据

    使用`StreamReader`的`ReadLine()`或`ReadBlock()`方法可以按行或指定长度接收数据。 4. **异步通信**: C#提供了异步API来处理网络通信,避免阻塞主线程。例如,`UdpClient.BeginReceive()`和`TcpClient....

    C#网络通信之TCP连接,客户端和服务端的tcp收发信息

    4. 通过NetworkStream的Write和Read方法发送和接收数据。 5. 完成通信后,记得关闭NetworkStream和TcpClient以释放资源。 服务端的TCP监听和接收信息则包括: 1. 创建一个TcpListener对象,设置监听的本地IP地址和...

    同步Sockets通讯代码(客户端)

    本示例展示了一个简单的C#同步Socket客户端代码,用于发送和接收数据。 首先,我们来看一下提供的代码片段。`SendReceiveData`方法接收一个字符串`strData`作为输入,并通过Socket与服务器进行通信。它返回一个布尔...

    JAVA代码实现类似C++的SOCKE编程中SELECT的功能。

    在Java编程中,有时我们需要处理多个网络连接,这时可以借鉴C++中的`select()`函数,它允许程序同时监听多个套接字(sockets)的状态。Java虽然没有直接提供`select()`函数,但通过`java.nio`包中的多路复用器...

    基于TCP协议的发送和接收端

    在接收数据时,使用Read()方法读取字节数组,再将其转换回字符串。 3. **异步编程**: - 在实际应用中,为了提高性能和用户体验,通常会使用异步方法处理网络通信。C#的BeginConnect(), BeginReceive(), BeginSend...

    Sockets-tutorial.tar.gz

    连接建立后,双方就可以通过read()和write()(或者send()和recv())函数进行数据交换。流式套接字保证了数据的顺序,而数据报套接字则不保证,因此在UDP编程中需自行处理数据的完整性。 6. 关闭与释放 当通信结束后...

    C# Socket通信源码

    数据接收使用Receive方法,它会阻塞直到有数据到达,或者设置Socket的接收超时属性。接收的数据也需要转换回字符串或其他形式以便处理。 在提供的"Socket通信源码"中,我们可以预期找到以下关键部分: 1. **服务器...

    基于C#的tcp图像传输

    例如,`NetworkStream.Write()`用于发送数据,`NetworkStream.Read()`用于接收数据。 5. **同步与异步通信**:C#提供了同步和异步两种通信方式。同步通信使用阻塞IO,如`Stream.Read()`和`Stream.Write()`,而异步...

    c#socket连接服务器

    一旦连接建立,双方都可以通过 `Send()` 和 `Receive()` 方法发送和接收数据。通常我们需要使用 `NetworkStream` 类进行更方便的字节流操作: ```csharp NetworkStream stream = new NetworkStream(clientSocket...

    tcp双工通信实现(c# 可执行)

    - 对于接收数据,可以使用NetworkStream的Read()方法,需要提供缓冲区来存放接收到的数据,并检查返回值,表示实际读取的字节数。 5. **关闭连接**: - 当通信完成后,记得关闭网络连接,以释放资源。可以调用...

    C# TCP 通信(数据、文件的传输)

    TcpClient用于客户端,负责与服务器建立连接并发送/接收数据。首先,创建一个TcpClient实例,然后调用Connect方法指定服务器的IP地址和端口号。连接成功后,可以通过GetStream方法获取NetworkStream对象,该对象可...

    c#利用TCP与川崎机器人通信

    - 接收数据时,使用Read方法读取数据。由于TCP是流式传输,需要循环读取,直到达到预期的数据量或遇到特定结束标志: ```csharp int bytesRead; while ((bytesRead = stream.Read(receivedData, 0, receivedData...

    VC 异步套接字发送命令 接受数据.rar

    在VC++编程环境中,异步套接字是网络通信中常用的一种技术,它允许程序在不阻塞主线程的情况下处理网络事件,如发送命令、接收数据等。在本压缩包"VC 异步套接字发送命令 接受数据.rar"中,包含的源码示例着重展示了...

    C#Socket通讯超清晰例子(带线程间访问)

    使用`NetworkStream`的`Write()`方法发送数据,`Read()`方法接收数据。注意,由于网络通信的异步性,接收数据可能需要循环读取,直到接收到完整的消息。 6. **异常处理**: Socket通信中可能会遇到各种网络问题,...

    C# TCP 客户端源码实现

    接着,创建TCP客户端的基本结构,包括连接服务器、发送数据和接收数据的功能。以下是一个简单的C# TCP客户端源码实现: ```csharp public class TcpClientExample { private TcpClient client; public void ...

    TcpListener 和TcpClient使用总结

    - **接收数据**:通过网络流的 **Read()** 方法读取数据到字节数组中,再将字节数组转换成原始格式。 #### 五、代码示例 下面是一段简化的服务器端代码示例: ```csharp using System; using System.Net.Sockets;...

    C#利用网络流对象实现的 聊天程序

    - 接收数据时,使用`Read`方法读取字节数组,再转换回字符串。需要注意的是,`Read`方法可能会返回少于预期的字节数,因此需要循环读取,直到所有数据都被接收。 4. **多线程与同步**: - 在服务器端,每个连接的...

    tcp例子c# server&client

    为了发送数据,我们使用NetworkStream的Write方法,而读取数据则使用Read方法。需要注意的是,由于TCP是流式协议,所以数据的读写需要考虑到流的同步问题,避免数据错乱。 接下来,我们转向TCP客户端(ClientDemo2...

    C#TCP同步通信程序实例 类似于QQ

    TcpClient用于客户端,它负责建立到服务器的连接并发送和接收数据。TcpListener则在服务器端运行,监听传入的连接请求,并接受新连接。 1. **创建TCP服务器**: 使用TcpListener,我们首先设置监听的IP地址和端口...

    C#TCP通信接口.rar

    `Write()`方法用于向网络发送数据,`Read()`方法用于从网络接收数据。需要注意的是,由于TCP的特性,读写操作可能需要处理异步和缓冲区管理。 4. **异常处理**:在实现TCP通信时,必须考虑网络异常,如连接失败、...

Global site tag (gtag.js) - Google Analytics