Java:TCP套接字数据丢失

时间:2019-01-23 22:36:58

标签: java sockets tcp

我正在尝试为我的游戏创建服务器(当然还有客户端)。它是用Java开发的,没有多余的库 或外部工作。目前已建立客户端和服务器连接,它发送定义的字节数(512)作为“ 套餐” 。每个程序包的类型(1个字节)都有一个ID,数据的主体(511个字节)有一个ID。通常,这种连接似乎有效。我目前面临的问题是,当我发送大量 尽可能快的数据量(地图〜10kb〜1300包),我似乎丢失了消息或接收到带有错误消息(例如:错误的package-ID)。我似乎无法弄清楚为什么会这样。据我了解,Java中的套接字使用TCP 协议,据我所知应该防止这些问题。

这是服务器的重要部分(在我看来):

void sendToClient(Queue<DataPackage> packages) {
    if(isConnected()){
        try {
            while(!packages.isEmpty()){
                this.out.write(packages.get().getByteData());
                packages.remove();
                this.out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
            if(!isConnected()){
                if(!ended){
                    ended = true;
                    server.getServerManager().getEventManager().publishServerEvent(new ServerLostConnectionToClientEvent(id, connection));
                }
            }
        }
    }
}

这是客户的重要部分(在我看来):

private void acceptData() throws UnsupportedPackageException {
    byte[] income = new byte[DataPackage.MAXPACKAGELENGTH];
    try {
        for(int length = in.read(income); length!=-1 && isConnected(); length = in.read(income)){
            income = Arrays.copyOf(income, DataPackage.MAXPACKAGELENGTH);   

            DataPackage dataPackage = null;
            try {
                dataPackage = new DataPackage(income, length);
            } catch (Exception ea) {ea.printStackTrace();}

            if(dataPackage!=null){

                if(!this.dataStreams.containsKey(dataPackage.getId())) this.dataStreams.put(dataPackage.getId(), new Queue<DataPackage>());
                Queue<DataPackage> dataStream = dataStreams.get(dataPackage.getId());
                if(dataPackage.isEnd()) {
                    this.dataStreams.remove(dataPackage.getId());   
                    handNewDataPackage(dataPackage, dataStream);
                }                   
            }

            income = new byte[DataPackage.MAXPACKAGELENGTH];
        }
    } catch (IOException e) {
        e.printStackTrace();
        if(this.client.run() && !ended){
            this.client.endClient();
            this.client.connectionLost(new ClientLostConnectionToServerEvent(this.socket));
        }
        ended = true;
    }
}

这是我建立连接的方式:

socket = new Socket(ip, port);
        socket.setTcpNoDelay(false);
        socket.setReceiveBufferSize(DataPackage.MAXPACKAGELENGTH);
        socket.setSendBufferSize(DataPackage.MAXPACKAGELENGTH);

        this.out = new BufferedOutputStream(socket.getOutputStream(), DataPackage.MAXPACKAGELENGTH);
        this.in = new BufferedInputStream(socket.getInputStream(), DataPackage.MAXPACKAGELENGTH);

您可以在此处查看整个项目(如果需要):https://github.com/reschiram/Game(最新分支:G-9)

很抱歉,如果这看起来像是关于如何编写Java套接字的另一个重复问题。我也在这里看到了几个类似的问题,但是似乎没有一个问题完全适合我的问题(或帮助我解决了该问题)。

0 个答案:

没有答案