Odbieranie dużej wiadomości przez UDP

0

Kiedy próbuję odebrać bardzo dużą wiadomość przez UDP, jak już wyżej napisałem, aplikacja wyłapuje mi wyjątek, którego wiadomość brzmi tak: "Komunikat wysłany na gniazdo datagramu był większy niż wewnętrzny bufor lub przekraczał limit sieciowy albo bufor do odbierania datagramów był mniejszy niż sam datagram".
Dodam, że mniejsze wiadomości odbieram bez problemu.
Wiadomości odbieram w pętli, bufor ma 256 bajtów, ale w metodzie Receive określam wielkość bufora.
O co z tym chodzi?

0

No dobra, zwiększyłem rozmiar bufora i działa, ale wolałbym żeby był on mniejszy. Da się tak zrobić?

0

pokaz ten kawalek kodu

0
int bytes;

                    while (true)
                    {
                        if (hasToStop)
                            break;

                        if (sock.Available > 0)
                        {
                            bytesReceived = new Byte[sock.Available];
                            bytes = sock.Receive(bytesReceived, bytesReceived.Length, 0);
                            recvdString += Encoding.ASCII.GetString(bytesReceived, 0, bytesReceived.Length);
                            onNewRecv(EventArgs.Empty);
                            bytesReceived = null;
                        }

                        Thread.Sleep(10);
                    }

Teraz to rozwiązałem tak jak jest no i wszystko OK. Czy jest sens zmniejszać rozmair tego bufora?

0

tworzenie bufora wielkosci sock.Available moze nie byc najlepszym wyjsciem, szczegolnie jesli przyjdzie wyjatkowo duza porcja danych, to program nagle zarezerwuje niesamowita ilosc miejsca niepotrzebnie

bufor polecam ustalic przed petla while
a w Recive odczytujesz tyle danych ile miesci sie w buforze i jesli to nie wszystkie dane, to czytasz dalej, czyli

byte[] buf = new byte[MAX_BUF_SIZE];
while(true)
{
  if (sock.Available > 0)
  {
    int readBytes = 0;
    do
    {
      readBytes = sock.Recive(buf, MAX_BUF_SIZE, 0);
      // zrob cos z przeczytanymi danymi
    }
    while (readBytes > 0)
  }
}

dzieki temu ze rozmiar bufora zostaje ciagle taki sam, panujesz lepiej nad tym ile pamieci potrzebuje twoj program

0

A czy w takiej sytuacji kiedy bufor będzie miał wielkość 256b, a wiadomość 512b to czy przy drugim odbieraniu danych bufor się wyczyści?

0

Zresztą teraz sprawdziłem twoje rozwiązanie i powrócił ten błąd.

0

Poradziłem sobie, musiałem ustawić większy bufor.
Ale mam inny problem.
Chciałem sobie zrobić auto reconnet, no i uczyniłem coś takiego:

 
        public void autoReconnect(object oMaxTries)
        {
            MessageBox.Show("SADS");
            int maxTries = (int)oMaxTries;
           // int tries = 0;
            Byte[] cmd = Encoding.ASCII.GetBytes("check\n");
            Byte[] buffor = new Byte[128];
            sock2 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            sock2.Connect(cAddr, cPort);
            sock2.ReceiveTimeout = 5;
            int bytesSent = 0, bytesReceived = 0;
            if (connectionStatus)
            {
                try
                {
                    MessageBox.Show("petla");
                    while (true)
                    {
                        if (hasToStop)
                            break;

                        bytesSent = sock2.Send(cmd, cmd.Length, 0);
                        bytesReceived = sock2.Receive(cmd, cmd.Length, 0);

                    }
                }
                catch (SocketException e)
                {
                    MessageBox.Show(e.Message, e.ErrorCode.ToString());
                    disconnect();
                }

            }
        }

Tą metodę odpalam w nowym wątku, w catchu ma być obsłużenie zerwania połączenia, ale to później. Problem jest w tym, że kod wykonuje się tylko jeśli na początku stoi ten MessageBox. Kiedy jest on- pokazuje mi się MB "petla" i MB z catcha. Kiedy go nie ma- żaden MB mi się nie pokazuje ani nic innego co mogłoby stać zamiast MB. O co z tym chodzi? ;/

0

Nikt nie wie?

1

Raczej błąd nie leży w messageboxie... Bez sensu, bo co niby tem messagebox ma robić...
Jedyne co mi przychodzi do głowy to to, że MS może spowalniać. Spróbuj dać testowo thread.sleep(1000) albo int i = 0; for (int j = 0; j < 1000000; j++) i = i + 1; i powiedz czy działa.

0

a próbowałeś wrzucić w pętlę wszystkie instrukcje od momentu jak tworzysz socketa?
wyglada tak jakby connectionStatus było false.
Być może jest jakoś tak że zaraz po tym jak tworzysz połączenie, w osobnym wątku uruchamiasz autoreconnecta. I w momecie jak autoreconnect dochodzi do Ifa zmienna connectionStatus jest false i dupa.

Tak w ogóle to tn AutoReconnect jakoś dziwnie wygląda, no ale nie wiem jak wyglada reszta programu.

0

Faktycznie, connectionStatus nie nadąża się zrobić na true. Dzięki :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1