【发布时间】:2013-05-21 05:48:05
【问题描述】:
我的问题是 C 套接字看起来与 Java 套接字的行为不同。我有一个 C 代理,我在工作负载生成器(用 Java 编写的 oltp 基准测试客户端)和 Postgres DB 的 JDBC 连接器之间对其进行了测试。 这很有效,可以将数据从一个转发到另一个,因为它应该。我们需要让这个代理在 Java 中工作,所以我使用了 java.net 中的普通 ServerSocket 和 Socket 类,但我无法让它工作。 Postgres 会返回一个认证错误信息,假设客户端没有发送正确的密码。
以下是 JDBC 协议的身份验证工作原理:
-client 发送请求以连接到指定数据库名称和用户名的数据库
-服务器以一次性质询消息(13 字节的随机内容消息)进行响应
-client 将此消息与用户密码连接并执行 md5 哈希
-server 比较从客户端得到的哈希值和他计算的哈希值
[执行此过程是为了避免重放攻击(如果客户端仅发送其密码的 md5 哈希,则攻击者可以重放此消息,假装他是客户端)]
所以我用 tcpdump 检查了数据包,它们看起来是正确的!大小完全符合其应有的大小,因此内容可能已损坏(??)
虽然数据库服务器有时会响应 ok 进行身份验证(取决于质询消息的值)!!然后 oltp 客户端发送了几个查询,但它在一段时间内崩溃了...... 我猜可能和编码有关,所以我尝试了 C 使用的编码(US-ANSII),但还是一样。
我在 C 和 Java 中都使用固定大小的字符或字节数组发送数据!
我真的没有更多的想法,因为我尝试了很多案例......
您对问题的猜测是什么?
这是一个有代表性的代码,可以帮助你更清楚地了解:
byte [] msgBuf;
char [] msgBufChars;
while(fromInputReader.ready()){
msgBuf = new byte[1024];
msgBufChars = new char[1024];
// read data from one party
int read = fromInputReader.read(msgBufChars, 0, 1024);
System.out.println("Read returned : " + read);
for(int i=0; i<1024; i++)
msgBuf[i] = (byte) msgBufChars[i];
String messageRead = new String(msgBufChars);
String messageToWrite = new String(msgBuf);
System.out.println("message read : "+messageRead);
System.out.println("message to write : "+new String(messageToWrite));
// immediatelly write data to other party (write the amount of data we read (read value) )
// there is no write method that takes a char [] as a parameter, so pass a byte []
toDataOutputStream.write(msgBuf, 0, read);
toDataOutputStream.flush();
}
一开始有几个消息交换,然后 Postgres 以身份验证失败消息作为响应。
感谢您的宝贵时间!
【问题讨论】:
-
不要使用Reader进行输入,使用InputStream处理原始字节,这样就不会通过字符串编码/解码改变任何字节