这是一些尝试使用OOB(紧急)数据的基本代码。我的问题是,如果客户端使用C或Java,则服务器部分的行为不相同。
小心一点,您可能认为这两个客户端都有些棘手,但是如果我使用C服务器(以获得对OOB的更好控制),那么无论我的服务器端OOB控件是什么,两个客户端的行为都完全相同。
首先是服务器(Java)部分:
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);
}
然后是客户端(Java)部分:
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");
然后是备用客户(C)部分:
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));
现在这就是我得到的(第一个C客户端,然后是Java客户端):
Accepting connection
ABC
DEF
GHI
J
Z
Accepting connection
ABC
DEF
GHI
J
0Z
看来Java服务器无法看到从C客户端发送的OOB数据。为什么
0
似乎丢失了?尚未,因为服务器至少已检测到流中的oob边界。 最佳答案
在所有Sockets实现中均不以相同的方式支持带外数据。就这么简单。
微软的建议在这里:
如果您正在编写新协议(protocol)并且需要带外数据,则建议您为紧急数据需要一个单独的连接,或者需要在应用程序层上对其进行多路复用。
因此,我的建议是,如果可以选择不要使用OOB数据。
关于Java带外(称为 "urgent data")数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15249635/