简体   繁体   English

套接字数据似乎没有通过客户端

[英]Socket data does not appear to be getting through to client

I've written some serverside socket handling code and I'm concerned that potentially my packets are not always making it back to the client. 我写了一些服务器端套接字处理代码,我担心可能我的数据包并不总是回到客户端。 I am logging all my events and in my log files it says I am sending the information. 我正在记录我的所有事件,并在我的日志文件中说它我正在发送信息。 But the client is also logging events and in their logs they say they do not receive anything. 但是客户端也在记录事件,并且在他们的日志中他们说他们没有收到任何东西。

My code to send the data is as follows: 我发送数据的代码如下:

public void write(Packet packet) {
    String data = packet.serialize();
    log("Send=[" + data + "]", "Write"); // log to file

    try {
        _writer.write(data);
        _writer.flush();
    } catch (Exception ex) {
        log(ex, "write");
    }
}

Each socket is created on a new thread and I create my writers and readers immediately like so (in the public run method): 每个套接字都是在一个新线程上创建的,我会立即创建我的编写器和读者(在公共运行方法中):

// _sockt is a Java Socket object
_writer = new BufferedWriter(new OutputStreamWriter(_socket
                    .getOutputStream()));
            _reader = new SocketReader(_socket);

SocketReader is just a wrapper class I created for listening for responses and has a public read method like so: SocketReader只是我为侦听响应而创建的包装类,并且有一个像这样的公共读取方法:

public String read() throws IOException, SocketTimeoutException {

    _socket.setSoTimeout(_timeOut);

    if(_reader == null)
        _reader = new BufferedReader(new InputStreamReader(_socket.getInputStream()));

            // read from the stream
    return new PacketDataInputStream(_reader).read();
}

The PacketDataInputStream wrapper class: PacketDataInputStream包装类:

BufferedReader _reader = null;

public PacketDataInputStream(BufferedReader reader)
{
    _reader = reader;
}

public String read() throws IOException, SocketException {

    StringBuilder builder = new StringBuilder();
    int c = 0;

    while((c = _reader.read()) != -1)
    {
        char ch = (char)c;

        builder.append(ch);

        if(ch == PacketConstants.ETX)
            break;
    }

    if(builder.length() > 0)
        return builder.toString();
    else
        return null;

}

The way I'm creating the actual socket listener objects is pretty standard I think: 我正在创建实际的套接字侦听器对象的方式非常标准我认为:

InetAddress address = InetAddress.getByName(IP);
        server = new ServerSocket( port, 0, address);

                    // My own manager class to handle all the sockets connected 
        WebSocketManager manager = new WebSocketManager(this);

        Socket connection = null;

        while(bContinue)
        {
            connection = server.accept();

            if(bContinue) {
                                    // assign the socket to a new thread and start
                                    // that thread
                manager.newSocket(connection);  
            } else {
                connection.close();
            }
        }
  • Is is possible that I'm using the wrong objects for sending the data back. 我可能正在使用错误的对象来发回数据。
  • Should I even be using a bufferedwriter and reader? 我应该使用缓冲式打字机和读卡器吗? I had thought that these were the best way to go but now I'm not so sure. 我原以为这是最好的方式,但现在我不太确定。

It's important to note that this does not happen all the time, just sporadically. 重要的是要注意,这不会偶尔发生,只是偶尔发生。 It could be the clients code having bugs but I need to make sure that I'm doing it correctly before going back to them. 它可能是客户端代码有bug但我需要确保我在回到它们之前正确地执行它。

This code is run on a Linux Ubuntu server. 此代码在Linux Ubuntu服务器上运行。 Logging occurs to a text file, nothing special there. 记录发生在文本文件中,没有什么特别之处。 My log files show the Send="" data going back to the client and no exception so it appears as if the .write and .flush() worked? 我的日志文件显示Send =“”数据返回给客户端,没有异常,所以看起来好像.write和.flush()工作? Socket connections are persistant and only closed by the client and or network issues. 套接字连接是持久的,只能由客户端和/或网络问题关闭。

UPDATE ----- Client Side code -------: 更新-----客户端代码-------:

I did manage to get some of the client side code for how they are handling the send and receiving of data (just in case it's more obvious on their end). 我确实设法获得了一些客户端代码,用于处理数据的发送和接收(以防万一它们的结尾更加明显)。 The client is actually connecting to this server via an Android device (if that helps). 客户端实际上是通过Android设备连接到此服务器(如果有帮助的话)。

Creation of socket 创建套接字

static final int BUFFER_SIZE = 20000;       // Maximum packet size

java.net.InetAddress server = java.net.InetAddress.getByName(url);
socket = new Socket(server, port);
// Set socket options:
socket.setReceiveBufferSize(BUFFER_SIZE);
socket.setSendBufferSize(BUFFER_SIZE);
socket.setKeepAlive(true);
socket.setTcpNoDelay(true);

Sending: 发送:

try {
            // Send the packet:
        OutputStream stream = socket.getOutputStream();
        stream.write(p.getByteArray ());
        stream.flush();

            // Update the time:
        lastPacketSendTime = new Date ();
    } catch (IOException e) {
        setError("Error sending packet (" + e.getMessage() + ")", ERROR_IO);
        return false;
    }

Receiving: 接收:

socket.setSoTimeout(timeout);
            // Get the reader:
        inputStream = socket.getInputStream();



     while (true) {
                    // Get the next character:
                int value = inputStream.read();
                    // Check for -1, indicating that the socket is closed:
                if (value == -1) {
                        // The socket is closed remotely, so close it locally as well:
                    disconnect();
                    inputStream = null;
                    return null;
                }
                                // ... and a bunch of other stuff to handle the actual data

                        }

EDIT 14-Nov: This is actually proving to be more of a problem now. 编辑11月14日:这实际上证明现在更成问题。 Both the client logs and the server logs appear to be sending. 客户端日志和服务器日志似乎都在发送。 But at times the data doesn't appear to come through or if it does it is sometimes coming through 10 - 30 - 60 second delayed. 但有时数据似乎没有通过,或者如果有的话,它有时会延迟10 - 30 - 60秒。

I can provide more information if required. 如果需要,我可以提供更多信息。

When you use BufferedReaders and BufferedWriters things get buffered. 当你使用BufferedReaders和BufferedWriters时,事情就会得到缓冲。 How about using the input and output streams directly.. Also, writers are character based, I don't know if you need to send binary data but if so that will be a problem with writers. 如何直接使用输入和输出流..此外,编写器是基于字符的,我不知道你是否需要发送二进制数据,但如果是这样,这将是编写器的问题。

I am not sure whether this will be to your any use or not.. but i am giving you the code i used for client server communication.. 我不确定这是否会对您有任何用处..但我给你的是用于客户端服务器通信的代码..

Client Side: 客户端:

public class ClientWala {

    public static void main(String[] args) throws Exception{

        Boolean b = true;
    Socket s = new Socket("127.0.0.1", 4444);

    System.out.println("connected: "+s.isConnected());


    OutputStream output = s.getOutputStream();
    PrintWriter pw = new PrintWriter(output,true);

    // to write data to server
    while(b){

        if (!b){

             System.exit(0);
        }

        else {
            pw.write(new Scanner(System.in).nextLine());
        }
    }


    // to read data from server
    InputStream input   = s.getInputStream();
    InputStreamReader isr = new InputStreamReader(input);
    BufferedReader br = new BufferedReader(isr);
    String data = null;

    while ((data = br.readLine())!=null){

        // Print it using sysout, or do whatever you want with the incoming data from server

    }




    }
}

Server Code: 服务器代码:

import java.io.*
import java.net.*;


public class ServerTest {

    ServerSocket s;

    public void go() {

        try {
            s = new ServerSocket(44457);

            while (true) {

                Socket incoming = s.accept();
                Thread t = new Thread(new MyCon(incoming));
                t.start();
            }
        } catch (IOException e) {

            e.printStackTrace();
        }

    }

    class MyCon implements Runnable {

        Socket incoming;

        public MyCon(Socket incoming) {

            this.incoming = incoming;
        }

        @Override
        public void run() {

            try {
                PrintWriter pw = new PrintWriter(incoming.getOutputStream(),
                        true);
                InputStreamReader isr = new InputStreamReader(
                        incoming.getInputStream());
                BufferedReader br = new BufferedReader(isr);
                String inp = null;

                boolean isDone = true;

                System.out.println("TYPE : BYE");
                System.out.println();
                while (isDone && ((inp = br.readLine()) != null)) {

                    System.out.println(inp);
                    if (inp.trim().equals("BYE")) {
                        System.out
                                .println("THANKS FOR CONNECTING...Bye for now");
                        isDone = false;
                        s.close();
                    }

                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                try {
                    s.close();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }

        }

    }

    public static void main(String[] args) {

        new ServerTest().go();

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM