Manipulace klesl pakety TCP v jazyce C #

hlasů
6

Posílám velké množství dat na jeden zátah mezi klientem a serverem psaný C #. To funguje dobře, když jsem běžet klient a server na mém lokálním počítači, ale když jsem dal server na vzdáleném počítači na internetu se zdá, k poklesu dat.

Posílám 20000 řetězce pomocí metody socket.Send () a zobrazí je pomocí smyčku, která dělá socket.Receive (). Každý řetězec je ohraničen unikátními znaky, které mohu použít k určení počtu obdržených (jedná se o protokol, chcete-li). Protokol je prokázáno, že i přes fragmentovaných zpráv je každý řetězec správně počítal. Na mém lokálním počítači jsem si všechny 20000, přes internet jsem něco mezi 17000-20000 dostat. Zdá se, že horší pomalejší připojení, že vzdálený počítač má. Chcete-li přidat k záměně, zapnutí Wireshark Zdá se, že snížení počtu odstraněných zpráv.

Za prvé, co je příčinou? Je to IP problém nebo něco s mým kódem špatného TCP /?

Za druhé, jak mohu obejít to? Příjem všechny 20000 řetězce je velmi důležité.

Socket příjmu kód:

private static readonly Encoding encoding = new ASCIIEncoding();
///...
while (socket.Connected)
{
    byte[] recvBuffer = new byte[1024];
    int bytesRead = 0;

    try
    {
        bytesRead = socket.Receive(recvBuffer);
    }
    catch (SocketException e)
    {
    if (! socket.Connected)
    {
        return;
    }
    }

    string input = encoding.GetString(recvBuffer, 0, bytesRead);
    CountStringsIn(input);
}

Zásuvka vysílá kód:

private static readonly Encoding encoding = new ASCIIEncoding();
//...
socket.Send(encoding.GetBytes(string));
Položena 26/08/2009 v 23:53
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
4

No je tu jedna věc, kterou se svým kódem v pořádku začít s, pokud jste počítání počtu hovorů na Receivekteré dokončena: Zdá se, že za předpokladu, že uvidíte tolik Receivevolání dokončit co jste udělali Sendhovory.

TCP je proud na bázi protokolu - neměli byste se starat o jednotlivých balíčcích nebo čte; měli byste se soustředit na čtení dat, očekávají, že někdy nebudete mít celou zprávu v jednom paketu a někdy můžete získat více než jednu zprávu v jediném čtení. (Jeden čtení nemusí odpovídat jednomu paketu, taky.)

Měli byste buď předponu každé metody s jeho délkou před odesláním, nebo mají oddělený mezi zprávami.

Odpovězeno 26/08/2009 v 23:57
zdroj uživatelem

hlasů
3

Pokud klesá pakety, uvidíte zpoždění při přenosu, protože má znovu přenášet zahozené pakety. To by mohlo být velmi významné, i když je tu možnost TCP nazývá selektivní potvrzení, která, je-li podporována obou stranách, bude to vyvolat opětovné odeslání pouze těch paketů, které byly vynechány, a ne každý paket od upustil jeden. Neexistuje žádný způsob, jak kontrolovat, zda v kódu. Ve výchozím nastavení můžete vždy předpokládat, že každý paket je dodáván, aby TCP a jestli existuje nějaký důvod, že nemůže dodat každý paket v pořádku, bude připojení klesat, a to buď pomocí časového limitu nebo jednoho konce Connetion zasláním RST paket.

To, co vidíte, je s největší pravděpodobností výsledkem Nagle algoritmu. Co to udělá, je namísto posílání každý bit dat, jak jste post, pošle jeden bajt a pak čeká na ACK z druhé strany. I když se to čekat, že agreguje všechny ostatní údaje, které chcete odeslat, a kombinuje ji do jednoho velkého balíku a pak jej pošle. Vzhledem k tomu, max velikost TCP je 65k, může se spojit docela dost dat do jednoho paketu, i když je to velmi nepravděpodobné, že k tomu dojde, zejména proto, že výchozí velikost vyrovnávací paměti Winsock je asi 10k nebo tak nějak (zapomněl jsem přesné částky). Navíc, je-li maximální velikost okna přijímače je menší než 65K, bude posílat jen tolik, kolik poslední inzerované velikosti okna přijímače. Velikost okna ovlivňuje také Nagle algoritmus stejně, pokud jde o kolik dat je možné agregovat před odesláním, protože nelze odeslat více než velikosti okna.

Důvodem, proč vidíte to je proto, že na internetu, na rozdíl od své síti, která nejprve ack zabere více času k návratu tak Naggle algoritmus agregáty více vašich dat do jednoho paketu. Místně, návrat je v podstatě okamžitý, takže je schopen posílat data tak rychle, jak můžete poslat ho do zásuvky. Můžete zakázat Naggle algoritmus na straně klienta pomocí setsockopt (winsock) nebo Socket.SetSocketOption (.NET), ale já doporučuji, že zakážete Naggling v zásuvce, pokud si nejste 100% jisti, že víte, co děláte. Je tam velmi dobrý důvod.

Odpovězeno 27/08/2009 v 00:09
zdroj uživatelem

hlasů
3

Rozhodně to není přes TCP chyba. TCP záruky objednávku, přesně-once dodání.

Které řetězce jsou „chybějící“? Vsadil bych se, že je to poslední,; pokusit splachování z vysílacího konce.

Kromě toho, vaše „protokol“ here (Beru o protokol aplikační vrstvy jste vynalézat) chybí: byste měli zvážit zaslání # objektů a / nebo jejich délky, takže přijímač neví, kdy to vlastně udělal jejich obdržení.

Odpovězeno 26/08/2009 v 23:55
zdroj uživatelem

hlasů
1

Jak dlouho každou strunu? Pokud nejsou přesně 1024 bajtů, budou sloučeny vzdáleného TCP / IP stack do jednoho velkého proudu, který čtete velké bloky ve svém volání přijímat.

Například při použití tři Odeslat volání poslat „A“, „B“ a „C“ bude s největší pravděpodobností přijde do svého vzdáleného klienta jako „ABC“ (buď jako vzdálený stohu nebo vlastní stack bude tlumit bajtů, dokud nejsou číst). Pokud potřebujete každý řetězec přijít, aniž by bylo sloučeno s jinými řetězci, podívejte se do přidávání do „protokol“ s identifikátorem ukázat začátek a konec každého řetězce, nebo alternativně konfigurovat zásuvku , aby se zabránilo ukládání do vyrovnávací paměti a kombinování paketů.

Odpovězeno 26/08/2009 v 23:55
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more