簡體   English   中英

在android套接字中:在服務器中僅接收到array []的一部分,套接字中是否有最大大小?

[英]in android socket: in the server only part of the array[] is received, is there a max size in socket?

我在android和服務器c#1-中開發了clint,當我將小字符串作為“ hello world”發送時,它已成功發送到服務器,並且客戶端也從服務器收到了響應msg

2-現在,我嘗試從android發送大字符串(實際上是圖像表示形式),字符串msg的大小為23.000字節。 大字符串的問題是:

1- the server c# did not receive  all the string bytes 
2- the response Msg did not received to the client

兩個實驗中的代碼都相同 ,只是字符串大小不同,請告訴我

這是客戶端android JAVA唯一的連接功能:public void ConnectToServer(){

    Thread ConnectToClient = new Thread(new Runnable() {

        @Override
        public void run() {try {
            Log.e("MESSAGE", "HERE void run");

            // time start here
            Log.e("MESSAGE", "Start time");
            long startTime = System.nanoTime();

            //Connect to socket 
            Log.e("MESSAGE", "HERE socket object");
            socket = new Socket(HOST, PORT);
              Log.e("MESSAGE", String.valueOf(client_str));
                        client_str = “hellow world”; //the problem if this string is huge i cannot write the string here it is too long


            DataOutputStream output_to_server = new DataOutputStream(socket.getOutputStream());
            output_to_server.writeBytes(client_str);
            output_to_server.flush();
               //receive ACK from (server)
                                        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    Log.e("MESSAGE", "Recieve the ACK from server");
                    recievedMsg = in.readLine();

                    Log.e("MESSAGE", String.valueOf(recievedMsg));

            //Update TextView
            Message msg = null;
            msg = textview_handler_thread.obtainMessage();
            msg.obj = recievedMsg;
            textview_handler_thread.sendMessage(msg);

        } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    ConnectToClient.start();
}

這是c#服務器:

   namespace CloudLet1Code
{
public static class Program
{
    public static void Main(string[] args)
    {
        IPAddress ipAdress = IPAddress.Parse("192.168.1.4");

            // Initializes the Listener
        TcpListener listener = new TcpListener(ipAdress, 4003);
        // Start Listeneting at the specified port
        listener.Start();

        Console.WriteLine("Server running - Port: 4003");
        Console.WriteLine("Local end point:" + listener.LocalEndpoint);
        Console.WriteLine("Waiting for connections...");

        Socket s = listener.AcceptSocket();
        // When accepted
        Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);
        byte[] b = new byte[1000000];
        string rcvd_msg = null;        
        int k = s.Receive(b);
        Console.WriteLine("Recieved...\n");

         for (int i = 0; i < k; i++)
         {
              Console.Write(Convert.ToChar(b[i]));
             rcvd_msg += Convert.ToChar(b[i]).ToString();
         }
        Console.WriteLine("\nrcvd_msg = " + rcvd_msg);
        listener.Stop();
        Console.WriteLine("Automatic message sent!");

        ///send ack
        ASCIIEncoding asen = new ASCIIEncoding();
        s.Send(asen.GetBytes("The string was recieved by the server number 1."));
        Console.WriteLine("\nSent Acknowledgement");
        // ack sent 
        s.Close();

    }
}

}更新代碼(c#)..接收數據塊,但仍無法提取字符串:

public static class Program
{
    public static void Main(string[] args)
    {
        IPAddress ipAdress = IPAddress.Parse("192.168.1.2");

        // Initializes the Listener
        TcpListener listener = new TcpListener(ipAdress, 4003);
        // Start Listeneting at the specified port
        listener.Start();

        Console.WriteLine("Server running - Port: 4003");
        Console.WriteLine("Local end point:" + listener.LocalEndpoint);
        Console.WriteLine("Waiting for connections...");

        Socket s = listener.AcceptSocket();
        // When accepted
        Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);


        MemoryStream bufferStream = new MemoryStream();
        byte[] buffer = new byte[1024];
        int count;
        //keep reading blocks from stream until there is no more data received
        //receive will block until there is data or the end of the stream has been reached
        while((count = s.Receive(buffer))!=0)
        {
            //write all received bytes into buffer stream ( which is in memory byte stream)
            bufferStream.Write(buffer, 0, count);
        }
        //get the entire brte array from the stream
        byte[] entireData = bufferStream.ToArray();
        //convert the received data to string using ascii incoding 
        String ReceivingDataString = System.Text.Encoding.ASCII.GetString(entireData);


        Console.WriteLine("Automatic message sent!");

        ///send ack

        ASCIIEncoding asen = new ASCIIEncoding();
        s.Send(asen.GetBytes("The string was recieved by the server number 1."));
        Console.WriteLine("\nSent Acknowledgement");
        // ack sent 
        s.Close();


    }

我猜問題出在int k = s.Receive(b); 在您的C#應用​​程序中。 這是因為這么大的數據塊不一定會在1個數據包中到達,這意味着在調用Socket.Receive()流的整個主體將不可用。 您可以嘗試將其循環放置,並繼續讀取所有數據,直到沒有可用數據為止(流的末尾)。 看看https://msdn.microsoft.com/zh-cn/library/8s4y8aff(v=vs.110).aspx ,尤其是底部的備注:

“如果使用的是面向連接的套接字,那么Receive方法將讀取盡可能多的數據”

這就是說,如果有任何可用數據,它將立即返回該數據-在返回所有可用數據並將其加載到緩沖區之前,它不會等待流結束(因為該流的長度可能為千兆字節,並且可能不會適合內存)。 以下示例顯示了一個快速示例,說明如何開始實現分塊接收數據並將其緩沖到MemoryStream中。

Socket s = yoursocket;
MemoryStream bufferStream = new MemoryStream();
byte[] buffer = new byte[1024];
int count;
// Keep reading blocks from the stream until there is no more data being received.
// As specified in the docs, Receive will block until there is data - or the end of the
// stream has been reached.
while((count = s.Receive(buffer)) != 0)
{
    // Write all received bytes into the buffer stream
    // (which is an in memory byte stream)
    bufferStream.Write(buffer, 0, count);
}

// Get the entire byte array from the stream
byte[] entireData = bufferStream.ToArray();

// Convert the received data to a string using ascii encoding
string receivedDataAsString = System.Text.Encoding.ASCII.GetString(entireData);

附帶說明一下,由於您發送圖像時,不應使用文本編碼(例如ASCII編碼),但這與阻止一次性接收所有數據的實際問題無關。 我希望這能使您對如何解決問題有所了解。

編輯:Socket.Receive()在遠程對等端結束流之前不會返回0。 不發送更多數據並不構成流的結尾。 因此,為了使上面的示例循環( while((count = s.Receive(buffer)) != 0)發生中斷,您的遠程對等while((count = s.Receive(buffer)) != 0)需要完全關閉流。(使用DataOutputStream.close()另外,您還需要捕獲Socket。引發的一些異常,並根據不同的情況接收遠程對等方在斷開連接的情況下(例如,超時)。如果您想處理數據而不必等待流關閉,您將需要在數據到達時使用它-在我的示例中,直接在while循環內。

while((count = s.Receive(buffer)) != 0)
    {
        // Convert the current buffer to a string (using the number of read bytes as the length of this string)
        string newText = System.Text.Encoding.ASCII.GetString(buffer, 0, count);
       //Console.WriteLine($"New data received: {newText}");
    }

is to ... 我對您的最佳建議是...

... 停止! ...

objective” here (and, therefore, “your immediate problem,”) is: “to succeed in sending 23KB by means of a socket.” 您在這里的目標”(因此也就是“您的直接問題”)是:“通過套接字成功發送23KB”。

在這一點上,您“正在做一個已經完成了數千次的工作。”實際上,您正在發明一個完整的 you are now doing, “it has already been done before.” STOP and look for which already knows how to solve this problem for you. 當然,這完全沒有必要,因為您現在在做什么,“它已經完成了。” 停下來 ,尋找已經知道如何為您解決該問題的 you can find it.) (您將需要解決許多錯誤。因此,隨時可以在可以找到它的捕獲已經調試過的代碼。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM