2013-03-06 11 views
7

Dưới đây là một số mã cơ bản đang cố gắng sử dụng dữ liệu OOB (Khẩn cấp). Vấn đề của tôi là phần máy chủ không hoạt động giống nhau nếu máy khách ở trong C hoặc trong Java. Quan trọng, bạn có thể nghĩ rằng điều gì đó phức tạp ở cả phía máy khách nhưng nếu tôi sử dụng máy chủ C (để kiểm soát tốt hơn OOB), thì cả hai khách hàng đều hoạt động giống như điều khiển OOB phía máy chủ của tôi.Dữ liệu Java Out Of Band (được gọi là "dữ liệu khẩn cấp")

Đầu máy chủ (Java) phần:

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); 
} 

Sau đó khách hàng (Java) phần:

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"); 

và sau đó khách hàng thay thế (C) phần:

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)); 

Bây giờ đây là những gì tôi nhận được (khách hàng C đầu tiên, sau đó là máy khách Java):

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

Dường như máy chủ Java không thể xem dữ liệu OOB được gửi từ phía máy khách C. Tại sao 0 dường như đã bị mất? Nó đã không, bởi vì máy chủ có ít nhất phát hiện ranh giới oob trong dòng.

+1

[Trích từ wikipedia] (http://en.wikipedia.org/wiki/Out-of-band#Computing): "Trong mạng máy tính, dữ liệu ngoài băng tần (được gọi là" ** dữ liệu khẩn cấp ** "trong TCP) trông - cho ứng dụng - giống như một luồng dữ liệu riêng biệt từ luồng dữ liệu chính." - Những người down down thân mến, đây không phải là một câu hỏi * khẩn cấp *, nó là về * dữ liệu khẩn cấp *. –

+0

Điều này không trả lời được câu hỏi của tôi. Trước tiên, bạn có thể nhận thấy rằng tôi đặt cờ OOBInline, thứ hai là nó hoạt động với một máy khách nhưng không hoạt động với một máy khách khác. –

+2

Đây không phải là câu trả lời. Nó chỉ là rất nhiều người downvoted câu hỏi của bạn bởi vì họ đọc "khẩn cấp" trong tiêu đề ... –

Trả lời

5

Dữ liệu ngoài băng tần không được hỗ trợ theo cùng một cách trên tất cả các triển khai Sockets. Nó đơn giản như vậy.

lời khuyên của Microsoft là ở đây:

Có, hiện nay, hai giải thích mâu thuẫn của RFC 793 (trong đó khái niệm được giới thiệu).

Việc thực hiện các dữ liệu OOB trong Berkeley Software Distribution (BSD) không phù hợp với các yêu cầu chủ định trong RFC 1122.

Cụ thể, con trỏ khẩn cấp TCP tại các điểm BSD để byte sau byte dữ liệu khẩn cấp và con trỏ khẩn cấp TCP tương thích RFC trỏ tới byte dữ liệu khẩn cấp. Kết quả là, nếu một ứng dụng gửi dữ liệu khẩn cấp từ một triển khai tương thích BSD đến một triển khai tương thích với RFC 1122, người nhận đọc byte dữ liệu khẩn cấp sai (nó đọc byte nằm sau byte chính xác trong luồng dữ liệu như dữ liệu khẩn cấp) byte).

Để giảm thiểu các vấn đề về khả năng tương tác, các nhà văn ứng dụng nên không sử dụng dữ liệu OOB trừ khi điều này là cần thiết để tương thích với một dịch vụ hiện có. Các nhà cung cấp ổ cắm Windows được khuyến khích ghi lại các ngữ nghĩa OOB (BSD hoặc RFC 1122) mà sản phẩm của họ thực hiện.

Nếu bạn đang viết một giao thức mới và cần phải có dữ liệu băng, tôi khuyên bạn cần kết nối riêng cho dữ liệu khẩn cấp hoặc bạn cần ghép nối nó ở lớp ứng dụng.

Vì vậy, lời khuyên của tôi là không sử dụng dữ liệu OOB nếu bạn có lựa chọn.

+2

Tại sao điều này lại được bình chọn? Có vẻ như là một điểm tốt và phù hợp với câu trả lời của OP rằng mã hoạt động khác nhau trên các nền tảng/phiên bản JVM khác nhau. – sharakan

1

Ok, điều này dường như liên quan đến việc triển khai JVM. Tôi đã thực hiện các thử nghiệm khác nhau, trên các hệ điều hành và JVM khác nhau.

Mọi thứ đều chính xác trên các Linux khác nhau với JDK 1.6 (Java 7 chưa được kiểm tra).

Nhưng mọi thứ sai với sư tử núi của tôi, nó hoạt động khác nhau tùy thuộc vào phiên bản Java. Dường như là lỗi JVM liên quan đến việc triển khai của Apple.

+0

Apple Mac OS dựa trên BSD Unix, theo câu trả lời của tôi. – Ben