代码之家  ›  专栏  ›  技术社区  ›  Dan

TCP客户端发送数据,但TCP服务器接收空值

  •  1
  • Dan  · 技术社区  · 7 年前

    我的应用程序中有一个TCP客户端和一个TCP服务器类。 客户端发送小字符串,如“1 | 2 |”或“1 | 11 |”

    客户端类

    public class TcpClient {
    
    
    private static final int MAX_DATA_RETRY = 1;
    private static final int PING_TIMEOUT = 100;
    
    private ClientThread thread;
    private boolean mRun = true;
    private PrintWriter mBufferOut;
    
    private String mIPAdress;
    
    
    private ArrayList<BufferDataItem> messageBuffer = new ArrayList<BufferDataItem>();
    private Socket mSocket;
    
    public TcpClient()
    {
        thread = new ClientThread();
        thread.start();
    }
    
    private class ClientThread extends Thread {
    
        @Override
        public void run() {
    
            while(mRun)
            {
                if(messageBuffer.size() <= 0)
                    continue;
    
                BufferDataItem currMessage = messageBuffer.get(0);
                currMessage.retryCount++;
                if(currMessage.retryCount > MAX_DATA_RETRY)
                {
                    messageBuffer.remove(0);
                    continue;
                }
    
                try {
                    //here you must put your computer's IP address.
                    InetAddress serverAddr = InetAddress.getByName(currMessage.ip);
    
    
    
                    //Log.e("TCP Client", "C: Connecting...");
    
                    try {
                        if(!serverAddr.isReachable(PING_TIMEOUT))
                        {
                            //only attempt to connect to devices that are reachable
                            messageBuffer.remove(0);
                            continue;
                        }
    
    
                        //create a socket to make the connection with the server
                        mSocket = new Socket(serverAddr, TcpManager.SERVER_PORT);
    
                        //Log.i("TCP Debug", "inside try catch");
                        //sends the message to the server
    
                        mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream())), true);
    
                        String message = currMessage.message;
                        if (mBufferOut != null && !mBufferOut.checkError()) {
                            Log.d("TCP SEND", "PUTTING IN BUFFER!  " + message);
                            mBufferOut.println(message);
                            listener.messageSent(message, currMessage.ip);
                            messageBuffer.remove(0);
                        }
                        mBufferOut.flush();
    
                    }
                    catch (ConnectException e) {
                        //Connection refused by found device!
                        //Log.e("TCP", "C: ConnectException   ip = "+currMessage.ip, e);
                        listener.hostUnreachable(currMessage.ip);
                        continue;
                    }
                    catch (Exception e) {
                        Log.e("TCP", "S: Error", e);
                        listener.messageSendError(e);
                    }
                    finally {
                        if(mSocket != null)
                            mSocket.close();
                    }
    
                }
                catch (Exception e) {
                    Log.e("TCP", "C: Error", e);
                    listener.messageSendError(e);
                    continue;
                }
            }
        }
    }
    
    
    
    /**
     * Sends the message entered by client to the server
     *
     * @param message text entered by client
     */
    public void sendMessage(String message) {
    
        BufferDataItem data = new BufferDataItem();
        data.message = message;
        data.ip = mIPAdress;
        messageBuffer.add(data);
    }
    
    public void sendMessage(String message, String ip) {
        mIPAdress = ip;
        BufferDataItem data = new BufferDataItem();
        data.message = message;
        data.ip = mIPAdress;
        messageBuffer.add(data);
    }
    
    
    /**
     * Close the connection and release the members
     */
    public void stopClient() {
        Log.i("Debug", "stopClient");
    
        mRun = false;
    
        if (mBufferOut != null) {
            mBufferOut.flush();
            mBufferOut.close();
        }
        mBufferOut = null;
    }
    
    private class BufferDataItem
    {
        public String message = "";
        public int retryCount = 0;
        public String ip = "";
    }
    
    private OnMessageSent listener = null;
    
    public interface OnMessageSent {
        public void messageSent(String message, String ip);
    
        public void hostUnreachable(String ip);
    
        public void messageSendError(Exception e);
    
    }
    
    public void setMessageSentListener(OnMessageSent listener)
    {
        this.listener = listener;
    }
    
    public void removeMessageSentListener()
    {
        this.listener = null;
    }
    

    服务器类

    public class TcpServer {
    
    private ServerThread thread;
    private boolean mRun = true;
    private boolean mEnd = false;
    
    
    public TcpServer()
    {
        thread = new ServerThread();
        thread.start();
    }
    
    private class ServerThread extends Thread {
    
        @Override
        public void run() {
    
            try {
                Boolean end = false;
                ServerSocket ss = new ServerSocket(TcpManager.SERVER_PORT);
                while (mRun) {
                    //Server is waiting for client here, if needed
                    Socket s = ss.accept();
                    BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
                    //PrintWriter output = new PrintWriter(s.getOutputStream(), true); //Autoflush
                    String st = input.readLine();
                    String remoteIP = s.getRemoteSocketAddress().toString();
                    int index = remoteIP.indexOf(":");
                    remoteIP = remoteIP.substring(1,index);
    
                    Log.d("TCP READ", "TCP READ: " + st);
                    if(st != null)
                        listener.messageReceived(st, remoteIP);
                    //output.println("Good bye and thanks for all the fish :)");
    
                    if(mEnd)
                    {
                        s.close();
                        mRun = false;
                    }
                }
    
                ss.close();
    
    
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    //Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
    //class at on asynckTask doInBackground
    public interface OnMessageReceived {
        public void messageReceived(String message, String ip);
    }
    
    private OnMessageReceived listener = null;
    
    public void SetMessageReceivedListener(OnMessageReceived listener)
    {
        this.listener = listener;
    }
    
    public void RemoveMessageReceivedListener()
    {
        this.listener = null;
    }
    

    }

    字符串st=输入。readLine();

    有人有什么建议吗?

    1 回复  |  直到 7 年前
        1
  •  0
  •   Zaboj Campula Massimiliano Peluso    7 年前

    我看到了服务器在一段时间后没有收到有效数据的两个可能原因。

    1. 服务器未关闭套接字 s mEnd 从未设置为true。客户端为每条消息打开一个新的TCP连接。服务器为连接创建套接字,但它从不关闭套接字,并且连接的服务器端保持打开状态。这是一种资源泄漏,可能会导致问题。

    2. ArrayList<BufferDataItem> messageBuffer . ArrayList 不是线程安全的集合,并且 messageBuffer 从多个线程使用。使用安全 synchronizedList 在这里请参阅 How do I make my ArrayList Thread-Safe? Another approach to problem in Java? Concurrent threads adding to ArrayList at same time - what happens?