连接到网络服务发现时,无法使用java套接字发送消息和接收

时间:2017-05-10 06:39:35

标签: java android sockets nsd

我正在使用网络服务发现服务发现对等并使用套接字连接到它们,所以套接字创建成功,但我无法发送消息或接收消息,所以下面是我的代码

MainActivity

public class MainActivity extends AppCompatActivity {

private static final String TAG = MainActivity.class.getSimpleName();
private NSDHelper mNsdHelper;
private int port;
private Context mContext;
ChatConnection mConnection;
private Button mDiscover, advertise_btn, connect_btn;
private Handler mUpdateHandler;
private TextView mStatusView;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mStatusView = (TextView) findViewById(R.id.status);
    mContext = MainActivity.this;

    mUpdateHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            String chatLine = msg.getData().getString("msg");
            addChatLine(chatLine);
        }
    };


    mConnection = new ChatConnection(mUpdateHandler);

    mNsdHelper = new NSDHelper(this);
    mNsdHelper.initNSD();

    advertise_btn = (Button) findViewById(R.id.advertise_btn);
    connect_btn = (Button) findViewById(R.id.connect_btn);


    advertise_btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // Register service
            if (mConnection.getLocalPort() > -1) {
                mNsdHelper.registerService(mConnection.getLocalPort());
            } else {
                Log.d(TAG, "ServerSocket isn't bound.");
            }
        }
    });


    connect_btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            NsdServiceInfo service = mNsdHelper.getChosenServiceInfo();
            if (service != null) {
                Log.d(TAG, "Connecting.");
                mConnection.connectToServer(service.getHost(),
                        service.getPort());
            } else {
                Log.d(TAG, "No service to connect to!");
            }
        }
    });

    mDiscover = (Button) findViewById(R.id.discover_btn);

    mDiscover.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mNsdHelper.discoverServices();
        }
    });
}

public void clickSend(View v) {
    EditText messageView = (EditText) this.findViewById(R.id.chatInput);
    if (messageView != null) {
        String messageString = messageView.getText().toString();
        if (!messageString.isEmpty()) {
            mConnection.sendMessage(messageString);
        }
        messageView.setText("");
    }
}

public void addChatLine(String line) {
    mStatusView.append("\n" + line);
}


@Override
protected void onPause() {
    if (mNsdHelper != null) {
        mNsdHelper.stopDiscovery();
    }
    super.onPause();
}


@Override
protected void onResume() {
    super.onResume();
    if (mNsdHelper != null) {
        mNsdHelper.discoverServices();
    }
}

@Override
protected void onDestroy() {
    mNsdHelper.tearDown();
    mConnection.tearDown();
    super.onDestroy();
}

}

ChatConnection

public class ChatConnection {

private Handler mUpdateHandler;
private ChatServer mChatServer;
private ChatClient mChatClient;

private static final String TAG = "ChatConnection";

private Socket mSocket;
private int mPort = -1;

public ChatConnection(Handler handler) {
    mUpdateHandler = handler;
    mChatServer = new ChatServer(handler);
}

public void tearDown() {
    mChatServer.tearDown();
    mChatClient.tearDown();
}

public void connectToServer(InetAddress address, int port) {
    mChatClient = new ChatClient(address, port);
}

public void sendMessage(String msg) {
    if (mChatClient != null) {
        mChatClient.sendMessage(msg);
    }
}

public int getLocalPort() {
    return mPort;
}

public void setLocalPort(int port) {
    mPort = port;
}


public synchronized void updateMessages(String msg, boolean local) {
    Log.e(TAG, "Updating message: " + msg);

    if (local) {
        msg = "me: " + msg;
    } else {
        msg = "them: " + msg;
    }

    Bundle messageBundle = new Bundle();
    messageBundle.putString("msg", msg);

    Message message = new Message();
    message.setData(messageBundle);
    mUpdateHandler.sendMessage(message);

}

private synchronized void setSocket(Socket socket) {
    Log.d(TAG, "setSocket being called.");
    if (socket == null) {
        Log.d(TAG, "Setting a null socket.");
    }
    if (mSocket != null) {
        if (mSocket.isConnected()) {
            try {
                mSocket.close();
            } catch (IOException e) {
                // TODO(alexlucas): Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    mSocket = socket;
}

private Socket getSocket() {
    return mSocket;
}

private class ChatServer {
    ServerSocket mServerSocket = null;
    Thread mThread = null;

    public ChatServer(Handler handler) {
        mThread = new Thread(new ServerThread());
        mThread.start();
    }

    public void tearDown() {
        mThread.interrupt();
        try {
            mServerSocket.close();
        } catch (IOException ioe) {
            Log.e(TAG, "Error when closing server socket.");
        }
    }

    class ServerThread implements Runnable {

        @Override
        public void run() {

            try {
                // Since discovery will happen via Nsd, we don't need to care which port is
                // used.  Just grab an available one  and advertise it via Nsd.
                mServerSocket = new ServerSocket(0);
                setLocalPort(mServerSocket.getLocalPort());

                while (!Thread.currentThread().isInterrupted()) {
                    Log.d(TAG, "ServerSocket Created, awaiting connection");
                    setSocket(mServerSocket.accept());
                    Log.d(TAG, "Connected.");
                    if (mChatClient == null) {
                        int port = mSocket.getPort();
                        InetAddress address = mSocket.getInetAddress();
                        connectToServer(address, port);
                    }
                }
            } catch (IOException e) {
                Log.e(TAG, "Error creating ServerSocket: ", e);
                e.printStackTrace();
            }
        }
    }
}

private class ChatClient {

    private InetAddress mAddress;
    private int PORT;

    private final String CLIENT_TAG = "ChatClient";

    private Thread mSendThread;
    private Thread mRecThread;

    public ChatClient(InetAddress address, int port) {

        Log.d(CLIENT_TAG, "Creating chatClient");
        this.mAddress = address;
        this.PORT = port;

        mSendThread = new Thread(new SendingThread());
        mSendThread.start();
    }

    class SendingThread implements Runnable {

        BlockingQueue<String> mMessageQueue;
        private int QUEUE_CAPACITY = 10;

        public SendingThread() {
            mMessageQueue = new ArrayBlockingQueue<String>(QUEUE_CAPACITY);
        }

        @Override
        public void run() {
            try {
                if (getSocket() == null) {
                    setSocket(new Socket(mAddress, PORT));
                    Log.d(CLIENT_TAG, "Client-side socket initialized.");

                } else {
                    Log.d(CLIENT_TAG, "Socket already initialized. skipping!");
                }

                mRecThread = new Thread(new ReceivingThread());
                mRecThread.start();

            } catch (UnknownHostException e) {
                Log.d(CLIENT_TAG, "Initializing socket failed, UHE", e);
            } catch (IOException e) {
                Log.d(CLIENT_TAG, "Initializing socket failed, IOE.", e);
            }

            while (true) {
                try {
                    String msg = mMessageQueue.take();
                    sendMessage(msg);
                } catch (InterruptedException ie) {
                    Log.d(CLIENT_TAG, "Message sending loop interrupted, exiting");
                }
            }
        }
    }

    class ReceivingThread implements Runnable {

        @Override
        public void run() {

            BufferedReader input;
            try {
                input = new BufferedReader(new InputStreamReader(
                        mSocket.getInputStream()));
                while (!Thread.currentThread().isInterrupted()) {

                    String messageStr = null;
                    messageStr = input.readLine();
                    if (messageStr != null) {
                        Log.d(CLIENT_TAG, "Read from the stream: " + messageStr);
                        updateMessages(messageStr, false);
                    } else {
                        Log.d(CLIENT_TAG, "The nulls! The nulls!");
                        break;
                    }
                }
                input.close();

            } catch (IOException e) {
                Log.e(CLIENT_TAG, "Server loop error: ", e);
            }
        }
    }

    public void tearDown() {
        try {
            getSocket().close();
        } catch (IOException ioe) {
            Log.e(CLIENT_TAG, "Error when closing server socket.");
        }
    }

    public void sendMessage(String msg) {
        try {
            Socket socket = getSocket();
            if (socket == null) {
                Log.d(CLIENT_TAG, "Socket is null, wtf?");
            } else if (socket.getOutputStream() == null) {
                Log.d(CLIENT_TAG, "Socket output stream is null, wtf?");
            }

            PrintWriter out = new PrintWriter(
                    new BufferedWriter(
                            new OutputStreamWriter(getSocket().getOutputStream())), true);
            out.println(msg);
            out.flush();
            updateMessages(msg, true);
        } catch (UnknownHostException e) {
            Log.d(CLIENT_TAG, "Unknown Host", e);
        } catch (IOException e) {
            Log.d(CLIENT_TAG, "I/O Exception", e);
        } catch (Exception e) {
            Log.d(CLIENT_TAG, "Error3", e);
        }
        Log.d(CLIENT_TAG, "Client sent message: " + msg);
    }
}

}

NSDHelper

public class NSDHelper {

private static final String TAG = NSDHelper.class.getSimpleName();

NsdManager mNsdManager;


public static final String SERVICE_TYPE = "_geoStorm._tcp.";

public String mServiceName = "DROIDDEVICE";


NsdManager.DiscoveryListener mDiscoveryListener;
NsdManager.RegistrationListener mRegistrationListener;
NsdManager.ResolveListener mResolveListener;
NsdServiceInfo mService;

private Context mContext;

public NSDHelper(Context _context) {
    mContext = _context;
    mNsdManager = (NsdManager) mContext.getSystemService(Context.NSD_SERVICE);


}

public void initNSD() {
    initializeResolveListener();
    initializeDiscoveryListener();
    initializeRegistrationListener();
}


/**
 * This method is to register NSD
 *
 * @param port
 */
public void registerService(int port) {
    NsdServiceInfo nsdServiceInfo = new NsdServiceInfo();
    nsdServiceInfo.setPort(port);
    nsdServiceInfo.setServiceName(mServiceName);
    nsdServiceInfo.setServiceType(SERVICE_TYPE);


    mNsdManager.registerService(nsdServiceInfo, NsdManager.PROTOCOL_DNS_SD,
            mRegistrationListener);
}

public void initializeResolveListener() {
    mResolveListener = new NsdManager.ResolveListener() {
        @Override
        public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
            Log.e(TAG, "Resolve failed" + errorCode);
        }

        @Override
        public void onServiceResolved(NsdServiceInfo serviceInfo) {
            Log.e(TAG, "Resolve Succeeded. " + serviceInfo);

            if (serviceInfo.getServiceName().equals(mServiceName)) {
                Log.d(TAG, "Same IP.");
                return;
            }
            mService = serviceInfo;
        }
    };
}


public void initializeDiscoveryListener() {
    mDiscoveryListener = new NsdManager.DiscoveryListener() {
        @Override
        public void onStartDiscoveryFailed(String serviceType, int errorCode) {
            Log.e(TAG, "Discovery failed: Error code:" + errorCode);
            mNsdManager.stopServiceDiscovery(this);
        }

        @Override
        public void onStopDiscoveryFailed(String serviceType, int errorCode) {
            Log.e(TAG, "Discovery failed: Error code:" + errorCode);
            mNsdManager.stopServiceDiscovery(this);
        }

        @Override
        public void onDiscoveryStarted(String serviceType) {
            Toast.makeText(mContext, "Discovery Started Successfully ",
                    Toast.LENGTH_LONG).show();
            Log.d(TAG, "Service discovery started");
        }

        @Override
        public void onDiscoveryStopped(String serviceType) {
            Log.i(TAG, "Discovery stopped: " + serviceType);
            Toast.makeText(mContext, "Discovery stopped", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onServiceFound(NsdServiceInfo serviceInfo) {
            Log.d(TAG, "Service discovery success" + serviceInfo);

            if (!serviceInfo.getServiceType().equals(SERVICE_TYPE)) {
                Toast.makeText(mContext, "Unknown Service Type", Toast.LENGTH_LONG).show();
            } else if (serviceInfo.getServiceName().equals(mServiceName)) {
                Log.d(TAG, "Same machine: " + mServiceName);
            } else if (serviceInfo.getServiceName().contains(mServiceName)) {
                mNsdManager.resolveService(serviceInfo, mResolveListener);
            }

            Log.d(TAG, serviceInfo.getPort() + "");
          //  Log.d(TAG, new InetSocketAddress(serviceInfo.getHost());)
        }

        @Override
        public void onServiceLost(NsdServiceInfo serviceInfo) {
            Log.e(TAG, "service lost" + serviceInfo);
            Toast.makeText(mContext, "service Lost" + serviceInfo, Toast.LENGTH_LONG).show();
            if (mService == serviceInfo) {
                mService = null;
            }
        }
    };
}

public void initializeRegistrationListener() {
    mRegistrationListener = new NsdManager.RegistrationListener() {
        @Override
        public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {

        }

        @Override
        public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {

        }

        @Override
        public void onServiceRegistered(NsdServiceInfo serviceInfo) {
            mServiceName = serviceInfo.getServiceName();
        }

        @Override
        public void onServiceUnregistered(NsdServiceInfo serviceInfo) {

        }
    };
}


public void discoverServices() {
    if (mNsdManager != null)
        mNsdManager.discoverServices(
                SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
}

public void stopDiscovery() {
    mNsdManager.stopServiceDiscovery(mDiscoveryListener);
}

public NsdServiceInfo getChosenServiceInfo() {
    return mService;
}

public void tearDown() {
    mNsdManager.unregisterService(mRegistrationListener);
    mNsdManager.stopServiceDiscovery(mDiscoveryListener);
    mNsdManager = null;
    mRegistrationListener = null;
  }
  }

我需要这方面的帮助,我如何使用套接字发送消息,因为我卡住了我没有得到任何东西,任何帮助将不胜感激。

0 个答案:

没有答案