我的问题是 C 套接字看起来与 Java 套接字的行为不同。我有一个 C 代理,我在工作负载生成器(用 Java 编写的 oltp 基准测试客户端)和 Postgres DB 的 JDBC 连接器之间对其进行了测试。这很有效,可以将数据从一个转发到另一个,因为它应该。我们需要让这个代理在 Java 中工作,所以我使用了 java.net 中的普通 ServerSocket 和 Socket 类,但我无法让它工作。Postgres 会返回一个认证错误信息,假设客户端没有发送正确的密码。
以下是 JDBC 协议的身份验证工作原理:
-client 发送连接到指定数据库名称和用户名的数据库的请求
-server 以一次性质询消息(13 字节的随机内容消息)作为响应
-client 将此消息与用户密码连接起来并执行 md5 哈希
-server 将从客户端获得的哈希与他计算的哈希进行比较
[执行此过程是为了避免重放攻击(如果客户端仅发送其密码的 md5 哈希,则攻击者可以重放此消息,假装他是客户端)]
所以我用 tcpdump 检查了数据包,它们看起来是正确的!大小完全符合其应有的大小,因此内容可能已损坏(??)
有时虽然数据库服务器对身份验证响应正常(取决于质询消息的值)!然后 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 以身份验证失败消息作为响应。
谢谢你的时间!