我正在尝试使用套接字将Android设备(客户端)与C#Server连接起来。我正在使用签名证书。
机器可以看到对方并尝试建立安全连接。 除了在Android上,我才会遇到错误。
javax.net.ssl.SSLProtocolException: Read error: ssl=0xa1f1c840: Failure in SSL library, usually a protocol error
error:100bd10c:SSL routines:ssl3_get_record:WRONG_VERSION_NUMBER (external/boringssl/src/ssl/s3_pkt.c:305 0xabf3fd97:0x00000000)
at com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:705)
...rest of stack trace
您能否为我提供解决此错误的解决方案。或者通过链接到示例来实现客户端和/或服务器端库,因为在互联网上没有信息如何使用套接字进行正确的SSL连接。
我正在使用代码在那些2之间建立连接。
这是服务器的简化版本
//Server start
X509Certificate2 cert = new X509Certificate2(cert, pass);
TcpListener server = new TcpListener(ip, port);
server.Start();
while (running)
{
TcpClient tcpClient = server.AcceptTcpClient();
Client client = new Client(this, tcpClient);
//In constructor I'm starting a new thread with method below
}
//Method mentioned above
void SetupConn()
{
NetworkStream netStream = client.GetStream();
SslStream ssl = new SslStream(netStream, false);
ssl.AuthenticateAsServer(prog.cert, false, SslProtocols.Tls, true);
dataStream = new DataStream(client.Client);
dataStream.Write("2012");
int hello = dataStream.ReadString();
... //Handling connection
}
//DataStream class
public DataStream(Socket clientSocket)
{
_clientSocket = clientSocket;
}
public void Write(string message)
{
int toSendLen = Encoding.ASCII.GetByteCount(message);
byte[] toSendBytes = Encoding.ASCII.GetBytes(message);
byte[] toSendLenBytes = BitConverter.GetBytes(toSendLen);
_clientSocket.Send(toSendLenBytes);
_clientSocket.Send(toSendBytes);
}
public String ReadString()
{
byte[] rcvLenBytes = new byte[4];
_clientSocket.Receive(rcvLenBytes);
int rcvLen = BitConverter.ToInt32(rcvLenBytes, 0);
byte[] rcvBytes = new byte[rcvLen];
_clientSocket.Receive(rcvBytes);
var ascii = Encoding.ASCII.GetString(rcvBytes);
return ascii;
}
现在在android中简化了客户端
SSLSocketFactory factory=(SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket socket=(SSLSocket) factory.createSocket(ip, port);
DataStream stream = new DataStream(socket);
Log.v("Log",stream.ReadString() + "");
stream.Write("2012");
DataStream类
public void Write(String message) {
byte[] toSendBytes = message.getBytes();
int toSendLen = toSendBytes.length;
byte[] toSendLenBytes = new byte[4];
toSendLenBytes[0] = (byte) (toSendLen & 0xff);
toSendLenBytes[1] = (byte) ((toSendLen >> 8) & 0xff);
toSendLenBytes[2] = (byte) ((toSendLen >> 16) & 0xff);
toSendLenBytes[3] = (byte) ((toSendLen >> 24) & 0xff);
try {
os.write(toSendLenBytes);
os.write(toSendBytes);
} catch (IOException e) {
e.printStackTrace();
}
}
public String ReadString() {
byte[] lenBytes = new byte[4];
try {
is.read(lenBytes, 0, 4);
} catch (IOException e) {
e.printStackTrace();
}
int len = (((lenBytes[3] & 0xff) << 24) | ((lenBytes[2] & 0xff) << 16) |
((lenBytes[1] & 0xff) << 8) | (lenBytes[0] & 0xff));
byte[] receivedBytes = new byte[len];
try {
is.read(receivedBytes, 0, len);
} catch (IOException e) {
e.printStackTrace();
}
return new String(receivedBytes, 0, len);
}
Android API 23
C#.Net 4.5
答案 0 :(得分:0)
对于这个错误,anwser有点奇怪,但最终我设法修复它。
问题出在C#DataStream类中使用套接字。相反,我应该使用SSLStream来写入和读取客户端的数据。我认为这可能是每个试图自己管理IO的人的常见错误,而不是使用BinaryWriter和BinaryReader。
SSLStream _clientSocket;
//DataStream class
public DataStream(SSLStream clientSocket)
{
_clientSocket = clientSocket;
}
public void Write(string message)
{
int toSendLen = Encoding.ASCII.GetByteCount(message);
byte[] toSendBytes = Encoding.ASCII.GetBytes(message);
byte[] toSendLenBytes = BitConverter.GetBytes(toSendLen);
_clientSocket.Write(toSendLenBytes);
_clientSocket.Write(toSendBytes);
}
public String ReadString()
{
byte[] rcvLenBytes = new byte[4];
_clientSocket.Read(rcvLenBytes, 0 , 4);
int rcvLen = BitConverter.ToInt32(rcvLenBytes, 0);
byte[] rcvBytes = new byte[rcvLen];
_clientSocket.Read(rcvBytes, 0, rcvLen);
var ascii = Encoding.ASCII.GetString(rcvBytes);
return ascii;
}