2013-03-06 13 views
7

Oto podstawowy kod próbujący użyć danych OOB (Pilne). Mój problem polega na tym, że część serwera nie zachowuje się tak samo, jeśli klient jest w języku C lub Java. Być może uważasz, że coś jest podchwytliwe po stronie klienta, ale jeśli korzystam z serwera C (aby uzyskać dokładniejszą kontrolę OOB), obaj klienci zachowują się dokładnie tak samo, niezależnie od tego, jaka jest moja kontrola OOB po stronie serwera.Java Out Of Band (dane "pilne dane")

Pierwszy serwer (Java), część:

Socket s = ss.accept(); 
s.shutdownOutput(); 
s.setOOBInline(true); 
InputStream is = s.getInputStream(); 
for (;;) { 
    byte []d = new byte[3]; 
    int l = is.read(d); 
    if (l==-1) break; 
    for (int i=0; i<l; i++) System.out.print((char)d[i]); 
    System.out.println(); 
    Thread.sleep(2000); 
} 

Następnie klient (Java), część:

Socket s = new Socket("localhost",61234); 
s.shutdownInput(); 
OutputStream os = s.getOutputStream(); 
byte []n = new byte[10]; 
for (int i=0; i<n.length; i++) n[i] = (byte)('A'+i); 
byte m = (byte)('0'); 
os.write(n); 
System.out.println("normal sent"); 
s.sendUrgentData(m); 
System.out.println("OOB sent"); 
os.write('Z'); 
System.out.println("normal sent"); 

, a następnie na przemian klienta (C), część:

s = socket(PF_INET,SOCK_STREAM,0); 
bzero(&a,sizeof(a)); 
a.sin_family = AF_INET; 
a.sin_port = htons(61234); 
a.sin_addr.s_addr = inet_addr("127.0.0.1"); 
connect(s,(struct sockaddr *)&a,sizeof(a)); 
shutdown(s,SHUT_RD); 
char m = '0'; 
char *n = "ABCDEFGHIJ"; 

printf("normal sent %d\n",write(s,n,strlen(n))); 
printf("OOB sent %d\n",send(s,&m,1,MSG_OOB)); 
printf("normal sent %d\n",write(s,"Z",1)); 

To właśnie dostaję (pierwszy klient C, następnie klient Java):

Accepting connection 
ABC 
DEF 
GHI 
J 
Z 
Accepting connection 
ABC 
DEF 
GHI 
J 
0Z 

Wygląda na to, że serwer Java nie jest w stanie wyświetlić danych OOB wysyłanych z klienta C-Client. Dlaczego wydaje się, że 0 został utracony? Nie, ponieważ serwer przynajmniej wykrył granicę oob w strumieniu.

+1

[Cytat z wikipedia] (http://en.wikipedia.org/wiki/Out-of-band#Computing): "W sieciach komputerowych dane pozapasmowe (zwane" ** pilnymi danymi **) "w TCP) wygląda - do aplikacji - jak oddzielny strumień danych z głównego strumienia danych." - Drodzy spadkobiercy, to nie jest * pilne * pytanie, chodzi o * pilne dane *. –

+0

To nie odpowiada na moje pytanie. Najpierw możesz zauważyć, że ustawiłem flagę OOBInline, po drugie, że działa ona z jednym klientem, ale nie z drugim. –

+2

To nie była odpowiedź. Po prostu wielu ludzi zlekceważyło twoje pytanie, ponieważ przeczytali w tytule "pilne" ... –

Odpowiedz

5

Dane poza pasmem nie są obsługiwane w taki sam sposób we wszystkich implementacjach gniazd. To takie proste.

rada Microsoftu jest tutaj:

Istnieją obecnie dwie przeciwstawne interpretacje RFC 793 (gdzie wprowadzono pojęcie).

Realizacja danych OOB w Berkeley Software Distribution (BSD) nie są zgodne z wymaganiami określonymi w RFC Host 1122.

Konkretnie, TCP pilne wskaźnik w punktach BSD do bajt po bajcie danych na pilną , a pilny wskaźnik TCP zgodny z RFC wskazuje na pilny bajt danych. W rezultacie, jeśli aplikacja wysyła pilne dane z implementacji zgodnej z BSD do implementacji kompatybilnej z RFC 1122, odbiornik odczytuje błędny pilny bajt danych (odczytuje bajt znajdujący się po poprawnym bajcie w strumieniu danych, jako pilne dane bajt).

Aby zminimalizować problemy związane z interoperacyjnością, zaleca się, aby twórcy aplikacji nie korzystali z danych OOB, chyba że jest to wymagane do współdziałania z istniejącą usługą. Dostawcy Windows Sockets są zachęcani do dokumentowania semantyki OOB (BSD lub RFC 1122), którą implementuje ich produkt.

Jeśli piszesz nowy protokół i potrzebujesz danych poza pasmem, sugerowałbym, abyś potrzebował osobnego połączenia dla pilnych danych lub musisz go zmultipleksować na warstwie aplikacji.

Dlatego moją radą jest nie używać danych OOB, jeśli masz wybór.

+2

Dlaczego zostało to odrzucone? Wydaje się, że jest to dobry punkt, zgodny z odpowiedzią OP, że kod zachowuje się inaczej na różnych platformach/wersjach JVM. – sharakan

1

OK, wydaje się to być związane z implementacją JVM. Wykonałem różne testy na różnych systemach operacyjnych i maszynach JVM.

Wszystko jest poprawne na różnych systemach Linux z JDK 1.6 (Java 7 nie testowana).

Ale coś jest nie tak z moim Mountain Lion, zachowuje się inaczej w zależności od wersji Java. Wydaje się być błędem JVM związanym z implementacją Apple.

+0

Apple Mac OS jest oparty na BSD Unix, jak na moją odpowiedź. – Ben