-
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个答案 按时间排序 按投票排序
-
想我当年还用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
-
应该是BufferedReader导致的,BufferedReader默认内部有缓冲区,size为8192,你应用层只有1000个字符,应该不满没有返回。可以将BufferedReader去掉试一下。另外,可以使用一下网络抓包工具查看一下是否有数据包传输。
2014年1月20日 09:19
相关推荐
使用`StreamReader`的`ReadLine()`或`ReadBlock()`方法可以按行或指定长度接收数据。 4. **异步通信**: C#提供了异步API来处理网络通信,避免阻塞主线程。例如,`UdpClient.BeginReceive()`和`TcpClient....
4. 通过NetworkStream的Write和Read方法发送和接收数据。 5. 完成通信后,记得关闭NetworkStream和TcpClient以释放资源。 服务端的TCP监听和接收信息则包括: 1. 创建一个TcpListener对象,设置监听的本地IP地址和...
本示例展示了一个简单的C#同步Socket客户端代码,用于发送和接收数据。 首先,我们来看一下提供的代码片段。`SendReceiveData`方法接收一个字符串`strData`作为输入,并通过Socket与服务器进行通信。它返回一个布尔...
在Java编程中,有时我们需要处理多个网络连接,这时可以借鉴C++中的`select()`函数,它允许程序同时监听多个套接字(sockets)的状态。Java虽然没有直接提供`select()`函数,但通过`java.nio`包中的多路复用器...
在接收数据时,使用Read()方法读取字节数组,再将其转换回字符串。 3. **异步编程**: - 在实际应用中,为了提高性能和用户体验,通常会使用异步方法处理网络通信。C#的BeginConnect(), BeginReceive(), BeginSend...
连接建立后,双方就可以通过read()和write()(或者send()和recv())函数进行数据交换。流式套接字保证了数据的顺序,而数据报套接字则不保证,因此在UDP编程中需自行处理数据的完整性。 6. 关闭与释放 当通信结束后...
数据接收使用Receive方法,它会阻塞直到有数据到达,或者设置Socket的接收超时属性。接收的数据也需要转换回字符串或其他形式以便处理。 在提供的"Socket通信源码"中,我们可以预期找到以下关键部分: 1. **服务器...
例如,`NetworkStream.Write()`用于发送数据,`NetworkStream.Read()`用于接收数据。 5. **同步与异步通信**:C#提供了同步和异步两种通信方式。同步通信使用阻塞IO,如`Stream.Read()`和`Stream.Write()`,而异步...
一旦连接建立,双方都可以通过 `Send()` 和 `Receive()` 方法发送和接收数据。通常我们需要使用 `NetworkStream` 类进行更方便的字节流操作: ```csharp NetworkStream stream = new NetworkStream(clientSocket...
- 对于接收数据,可以使用NetworkStream的Read()方法,需要提供缓冲区来存放接收到的数据,并检查返回值,表示实际读取的字节数。 5. **关闭连接**: - 当通信完成后,记得关闭网络连接,以释放资源。可以调用...
TcpClient用于客户端,负责与服务器建立连接并发送/接收数据。首先,创建一个TcpClient实例,然后调用Connect方法指定服务器的IP地址和端口号。连接成功后,可以通过GetStream方法获取NetworkStream对象,该对象可...
- 接收数据时,使用Read方法读取数据。由于TCP是流式传输,需要循环读取,直到达到预期的数据量或遇到特定结束标志: ```csharp int bytesRead; while ((bytesRead = stream.Read(receivedData, 0, receivedData...
在VC++编程环境中,异步套接字是网络通信中常用的一种技术,它允许程序在不阻塞主线程的情况下处理网络事件,如发送命令、接收数据等。在本压缩包"VC 异步套接字发送命令 接受数据.rar"中,包含的源码示例着重展示了...
使用`NetworkStream`的`Write()`方法发送数据,`Read()`方法接收数据。注意,由于网络通信的异步性,接收数据可能需要循环读取,直到接收到完整的消息。 6. **异常处理**: Socket通信中可能会遇到各种网络问题,...
接着,创建TCP客户端的基本结构,包括连接服务器、发送数据和接收数据的功能。以下是一个简单的C# TCP客户端源码实现: ```csharp public class TcpClientExample { private TcpClient client; public void ...
- **接收数据**:通过网络流的 **Read()** 方法读取数据到字节数组中,再将字节数组转换成原始格式。 #### 五、代码示例 下面是一段简化的服务器端代码示例: ```csharp using System; using System.Net.Sockets;...
- 接收数据时,使用`Read`方法读取字节数组,再转换回字符串。需要注意的是,`Read`方法可能会返回少于预期的字节数,因此需要循环读取,直到所有数据都被接收。 4. **多线程与同步**: - 在服务器端,每个连接的...
为了发送数据,我们使用NetworkStream的Write方法,而读取数据则使用Read方法。需要注意的是,由于TCP是流式协议,所以数据的读写需要考虑到流的同步问题,避免数据错乱。 接下来,我们转向TCP客户端(ClientDemo2...
TcpClient用于客户端,它负责建立到服务器的连接并发送和接收数据。TcpListener则在服务器端运行,监听传入的连接请求,并接受新连接。 1. **创建TCP服务器**: 使用TcpListener,我们首先设置监听的IP地址和端口...
`Write()`方法用于向网络发送数据,`Read()`方法用于从网络接收数据。需要注意的是,由于TCP的特性,读写操作可能需要处理异步和缓冲区管理。 4. **异常处理**:在实现TCP通信时,必须考虑网络异常,如连接失败、...