将Android客户端连接到C#服务器

3
我开发了一个小型的客户端服务器(安卓设备上的客户端发送数据,PC上的服务器接收并打印出来),它只能工作一次(通过从安卓设备发送数据到PC),然后我需要关闭安卓应用程序并再次运行它? 顺便说一句,我在PC上有客户端应用程序,它可以正常工作,我可以从它发送数据,服务器也能接收到,但对于安卓客户端来说不行!
以下是安卓代码:
    public class MainActivity extends Activity {

    private TCPClient mTcpClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final EditText editText = (EditText) findViewById(R.id.edit_message);
        Button send = (Button)findViewById(R.id.send_button);        

        // connect to the server
        new connectTask().execute("");

        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                String message = editText.getText().toString(); 

                //sends the message to the server
                if (mTcpClient != null) {
                    mTcpClient.sendMessage(message);
                }

                editText.setText("");
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    public class connectTask extends AsyncTask<String,String,TCPClient> {

        @Override
        protected TCPClient doInBackground(String... message) {

            mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
                @Override

                public void messageReceived(String message) {

                    publishProgress(message);
                }
            });
            mTcpClient.run();

            return null;
        }

        @Override
        protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values); 
        }
    }
  }

还有TCPClient类:

    public class TCPClient {

    private String serverMessage;
    public static final String SERVERIP = "192.168.0.104"; 
    public static final int SERVERPORT = 4444;
    private OnMessageReceived mMessageListener = null;
    private boolean mRun = false;

    PrintWriter out;
    BufferedReader in;
    DataOutputStream dataOutputStream = null;

    //OutputStream os;

    public TCPClient(OnMessageReceived listener) {
        mMessageListener = listener;
    }

    public void sendMessage(String message){
        if (out != null && !out.checkError()) {

            /*
            String toSend = "a";
            byte[] toSendBytes = toSend.getBytes();

            int toSendLen = toSendBytes.length;
            byte[] toSendLenBytes = new byte[4];
            toSendLenBytes[0] = (byte)(toSendLen & 0xff);
            toSendLenBytes[1] = (byte)((toSendLen >> 8) & 0xff);
            toSendLenBytes[2] = (byte)((toSendLen >> 16) & 0xff);
            toSendLenBytes[3] = (byte)((toSendLen >> 24) & 0xff);
            try {
                os.write(toSendLenBytes);
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            try {
                os.write(toSendBytes);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            */
           out.print(message);            
           out.flush();           


        }
    }

    public void stopClient(){
        mRun = false;
    }

    public void run() {

        mRun = true;

        try {

            InetAddress serverAddr = InetAddress.getByName(SERVERIP);

            Log.e("TCP Client", "C: Connecting...");

            Socket socket = new Socket(serverAddr, SERVERPORT);    

            ///
            //os = socket.getOutputStream();

            if(socket.isBound()){
                Log.i("SOCKET", "Socket: Connected");            
            }
            else{
                Log.e("SOCKET", "Socket: Not Connected");
            }
            try {

                out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

                /*
                dataOutputStream = new DataOutputStream(socket.getOutputStream());
                byte[] bytes = new byte[] {1}; 
                dataOutputStream.write(bytes, 0, bytes.length);
                */
                Log.e("TCP Client", "C: Sent.");                

                Log.e("TCP Client", "C: Done.");

                if(out.checkError())
                {
                    Log.e("PrintWriter", "CheckError");
                }

                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                while (mRun) {
                    serverMessage = in.readLine();

                    if (serverMessage != null && mMessageListener != null) {
                        mMessageListener.messageReceived(serverMessage);
                    }
                    serverMessage = null;

                }


                Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + serverMessage + "'");


            } catch (Exception e) {

                Log.e("TCP", "S: Error", e);

            } finally {

                socket.close();
            }

        } catch (Exception e) {

            Log.e("TCP", "C: Error", e);

        }

    }

    public interface OnMessageReceived {
        public void messageReceived(String message);
    }

}

最后是C#服务器代码:

class Program
{
    static Socket listeningSocket;
    static Socket socket;
    static Thread thrReadRequest;
    static int iPort = 4444;
    static int iConnectionQueue = 100;

    static void Main(string[] args)
    {
        Console.WriteLine(IPAddress.Parse(getLocalIPAddress()).ToString());
        try
        {                
            listeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //listeningSocket.Bind(new IPEndPoint(0, iPort));                                
            listeningSocket.Bind(new IPEndPoint(IPAddress.Parse(getLocalIPAddress()), iPort));
            listeningSocket.Listen(iConnectionQueue);

            thrReadRequest = new Thread(new ThreadStart(getRequest));
            thrReadRequest.Start();
        }
        catch (Exception e)
        {
            Console.WriteLine("Winsock error: " + e.ToString());
            //throw;
        }            
    }

    static private void getRequest()
    {
        int i = 0;
        while (true)
        {
            i++;
            Console.WriteLine("Outside Try i = {0}", i.ToString());

            try
            {
                socket = listeningSocket.Accept();

                // Receiving
                //byte[] rcvLenBytes = new byte[4];
                //socket.Receive(rcvLenBytes);
                //int rcvLen = System.BitConverter.ToInt32(rcvLenBytes, 0);
                //byte[] rcvBytes = new byte[rcvLen];
                //socket.Receive(rcvBytes);
                //String formattedBuffer = System.Text.Encoding.ASCII.GetString(rcvBytes);

                byte[] buffer = new byte[socket.SendBufferSize];
                int iBufferLength = socket.Receive(buffer, 0, buffer.Length, 0);
                Console.WriteLine("Received {0}", iBufferLength);
                Array.Resize(ref buffer, iBufferLength);
                string formattedBuffer = Encoding.ASCII.GetString(buffer);

                Console.WriteLine("Data received by Client: {0}", formattedBuffer);

                if (formattedBuffer == "quit")
                {
                    socket.Close();
                    listeningSocket.Close();
                    Environment.Exit(0);
                }

                Console.WriteLine("Inside Try i = {0}", i.ToString());
                Thread.Sleep(500);
            }
            catch (Exception e)
            {
                //socket.Close();
                Console.WriteLine("Receiving error: " + e.ToString());
                Console.ReadKey();
                //throw;
            }

            finally
            {
                socket.Close();
                //listeningsocket.close();
            }
        }
    }

    static private string getLocalIPAddress()
    {
        IPHostEntry host;
        string localIP = "";
        host = Dns.GetHostEntry(Dns.GetHostName());
        foreach (IPAddress ip in host.AddressList)
        {
            if (ip.AddressFamily == AddressFamily.InterNetwork)
            {
                localIP = ip.ToString();
                break;
            }
        }
        return localIP;
    }
}

这里还有一个代码链接(点击进入)

我需要帮忙吗?


你想用C#做什么?发送数据还是接收数据? - MDMalik
2个回答

1

对我来说,稍微调整一下相同的代码就可以正常工作。

    try
    {
        socket = listeningSocket.Accept();
        Console.WriteLine("Connectd...");
        while (true)
        {
            try
            {

                // Receiving

                byte[] buffer = new byte[socket.SendBufferSize];
                int iBufferLength = socket.Receive(buffer, 0, buffer.Length, 0);
                Console.WriteLine("Received {0}", iBufferLength);
                Array.Resize(ref buffer, iBufferLength);
                string formattedBuffer = Encoding.ASCII.GetString(buffer);

                Console.WriteLine("Android Says: {0}", formattedBuffer);

                if (formattedBuffer == "quit")
                {
                    socket.Close();
                    listeningSocket.Close();
                    Console.WriteLine("Exiting");
                    Environment.Exit(0);
                }

                //Console.WriteLine("Inside Try i = {0}", i.ToString());
                Thread.Sleep(500);
            }
            catch (Exception e)
            {
                //socket.Close();
                Console.WriteLine("Receiving error: " + e.ToString());
                Console.ReadKey();
                //throw;
            }


        }
    }
    catch (Exception e)
    {
        //socket.Close();
        Console.WriteLine("Error After Loop: " + e.ToString());
    }
    finally
    {
        Console.WriteLine("Closing Socket");
        socket.Close();
        //listeningsocket.close();
    }

1
看到这个修复。对于


out.println(message);            
           out.flush();  

C#读取应该是:
  socket = listeningSocket.Accept();
                    using (NetworkStream nt = new NetworkStream(socket))
                    {
                        using (StreamReader reader = new  StreamReader(nt))
                        {
                            string line;
                            string line;

                        //  while ((line = reader.ReadLine()) != null)//as networkstream never got eof. was using it as replacement while(true)                            // {
                          while (true)
                          {
                            try
                            {
                                line = reader.ReadLine();
                            }
                            catch (IOException)
                            {
                                break;
                            }
                            Console.WriteLine(line);
                           }
                        }//using reader
                    }//using ns

有三种方法可以做:

    1)using fixed size messages . like we will send only 100 bytes . 
      and we will        receive only 100 bytes

    2)dinamic way . size of message ,then the message itself . 
      like we will send [message.length][message] then on opposite side
      we will receive the size message then read entire message 

    3) using marker . we will send message with end marker 
       (for example \n in our case) 
      we will use stream to read entire message sent to us till reaching that marker . 
      and most stream has readline() that will read till reaching \n

我觉得你想采用第二种方式。我没有仔细看是哪里有问题,而且你还给那个选项加了注释。主要问题可能与小端和大端有关。


非常感谢,当我制作C#客户端时,它可以正常工作,而不需要使用NetworkStream和StreamReader,现在我很困惑,如何知道我应该使用这些? - Ahmad Z. Tibi
@AhmedYazanTibi 我为你改进了答案。 - qwr
我无法理解while循环,它是否应该在没有发送空消息时退出?我尝试从客户端按下按钮(发送null),但while循环仍在循环? - Ahmad Z. Tibi
@AhmedYazanTibi 不,我只是这样实现 while(true)。你必须从客户端关闭socket以退出,并且它会抛出异常,使用者应该处理。等我改为更正确的方式。 - qwr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接