java TCP套接字消息中断

Posted

技术标签:

【中文标题】java TCP套接字消息中断【英文标题】:java TCP socket message breaks 【发布时间】:2011-09-27 19:43:03 【问题描述】:

我在 java 中有一个 java 客户端-服务器应用程序,两者都使用包含发送/接收消息的相同连接类。 出于某种原因,我发送的某些消息的接收顺序不正确:

这是代码

//set up
_in = new BufferedReader(new InputStreamReader(this._socket.getInputStream()));
_out = new BufferedWriter(new OutputStreamWriter(this._socket.getOutputStream()));
this._socket.setSoTimeout(S_TIMEOUT);


public synchronized boolean send(String message)
    try 
        _out.write(message);
        _out.write(Connection.DELIMITER);
        _out.flush();
        return true;
     catch (IOException e) 
    
    return false;



public String receive()
    int c;
    try 
        String message = "";
        System.out.println("Getting message:");
        c = _in.read();
        while(c != -1 && c != Connection.DELIMITER) 
            message += (char) c;
            c = _in.read();
        
        if (c == -1) 
            return null;
        
        return message;
     catch (IOException e)  
    return null;

某些消息,例如“new_order”可能会返回“ew_ord”。 有些字符丢失了,有些则单独发送。这看起来很奇怪,因为它的 TCP

这可能是与编码相关的问题吗?

分隔符为 (char) 0 套接字超时为 20000(即 20 秒)。每 10 秒我发送一条空消息以确保套接字不会关闭

编辑: 虽然它是使用扫描仪解决的,但我必须说原始代码在很长一段时间(几周)内适用于许多消息/各种机器,然后突然无法在一台特定机器上处理一条特定消息(其他消息通过就好了)。我已经在 J​​ava 中多次完成套接字数据传输,并且我已经编写了许多读/写方法来处理套接字。这是我第一次遇到这种情况。

虽然在原始代码中我设置了编码(在发布的代码中我没有),但我认为问题与编码有关。在某一时刻,收到的消息每隔一个字符就会丢失。之后我对其进行了一些更改,并且消息的第一个/第二个字符在单独的消息中收到。据我了解,这要么是编码问题,要么是消息发送者机器上运行的某些防火墙/其他安全程序决定过滤传出数据包。

【问题讨论】:

Connection.DELIMITERS_TIMEOUT 目前定义为什么? 与您的问题无关,但为了效率,我建议在收到消息时使用StringBuilder 【参考方案1】:

尝试用扫描仪替换您的接收,让它为您完成工作。

// in your setup
Scanner sc = new Scanner(_in).useDelimiter(Connection.DELIMETER);

public String receive() 
    try 
        return sc.next();
     catch(IOException e) 
        return "";
    


【讨论】:

【参考方案2】:

首先,我会确保您在这些 catch 块中打印异常。

然后,您将使用平台默认编码将字符转换为字节。如果这两个进程在不同的机器上运行,它们可能使用不同的编码。我会确保您在设置 Reader 和 Writer 时指定编码。

【讨论】:

【参考方案3】:

您可以使用 UTF 编码来获取完整的消息字符串。

你可以试试这个代码,我很确定这个代码,因为我在我的聊天应用程序中使用了它。

String data=" ";

socket = new Socket("localhost",999);
while(true)
        
           dos = new DataOutputStream(socket.getOutputStream());
           dis =  new DataInputStream(socket.getInputStream());
           data = dis.readUTF();
           jta.append(data +"\n");
        

其中 jta 是 JTextArea。

用于客户端

现在服务器端:

try


server = new ServerSocket(999);     

Socket  soc = server.accept();  

        while(true)
        
            String data="";
            try
                               
                dis = new DataInputStream(soc.getInputStream());
                dos = new DataOutputStream(soc.getOutputStream());
                data = dis.readUTF();
            
            catch(Exception e)
             
            jta.append(data + "\n");
        
    
    catch (IOException e) 
    
        JOptionPane.showMessageDialog(this, e);
        System.exit(-1);
    

【讨论】:

以上是关于java TCP套接字消息中断的主要内容,如果未能解决你的问题,请参考以下文章

在erlang中中断gen_tcp:recv

java.net.SocketException:套接字关闭 TCP 客户端服务器通信 [重复]

Java TCP/IP Socket深入剖析socket——TCP套接字的生命周期

使用 gen_tcp:send/2 通过套接字发送消息

Linux:在 TCP 套接字上发送整个消息或不发送任何消息

套接字阻止在 Java 服务器和 Python 客户端之间发送消息