Uygulamamız için SftpConnections Havuzu'nu uygulamaya çalışırken bir sorun yaşıyoruz.SSH Sunucu Kimliği hiçbir zaman alınmadı - Handshake Deadlock [SSHJ]
Şu anda kullandığınızSSHJ
taşıma kitaplık olarak (Schmizz) ve biz sadece bizim geliştirme ortamında taklit edemez bir sorunla karşı karşıya (ama hata bazen sadece 10 dakika sonra, bazen üç gün sonra, üretimde rastgele gösteren tutar).
SFTP yoluyla dosya göndermeye çalışırken sorun, iplik TransportImpl
sınıfından 'schmizz gelen init
yöntemde kilitli alır edilir:
@Override
public void init(String remoteHost, int remotePort, InputStream in, OutputStream out)
throws TransportException {
connInfo = new ConnInfo(remoteHost, remotePort, in, out);
try {
if (config.isWaitForServerIdentBeforeSendingClientIdent()) {
receiveServerIdent();
sendClientIdent();
} else {
sendClientIdent();
receiveServerIdent();
}
log.info("Server identity string: {}", serverID);
} catch (IOException e) {
throw new TransportException(e);
}
reader.start();
}
isWaitForServerIdentBeforeSendingClientIdent yüzden her şeyden önce, bizim için YANLıŞ'tır
: günlükleri göründüğü gibi istemci (biz), bizim kimlik gönder "Müşteri kimlik dize: blabla"
Sonra receiveServerIdent
için dönüş var: Sunucu asla kimliği ile cevap olarak
private void receiveServerIdent() throws IOException
{
final Buffer.PlainBuffer buf = new Buffer.PlainBuffer();
while ((serverID = readIdentification(buf)).isEmpty()) {
int b = connInfo.in.read();
if (b == -1)
throw new TransportException("Server closed connection during identification exchange");
buf.putByte((byte) b);
}
}
iplik, kontrol yine geçmez. Kod bu Süre döngüde sıkışmış gibi görünüyor. Hiçbir zaman aşımı veya SSH istisnası atılmaz, müvekkilim sonsuza kadar beklemeye devam ediyor ve iş parçacığı kilitlenmiyor.
Bu
readIdentification
yöntemin impl geçerli:
private String readIdentification(Buffer.PlainBuffer buffer)
throws IOException {
String ident = new IdentificationStringParser(buffer, loggerFactory).parseIdentificationString();
if (ident.isEmpty()) {
return ident;
}
if (!ident.startsWith("SSH-2.0-") && !ident.startsWith("SSH-1.99-"))
throw new TransportException(DisconnectReason.PROTOCOL_VERSION_NOT_SUPPORTED,
"Server does not support SSHv2, identified as: " + ident);
return ident;
}
sunucu bağlantıyı kesti sanki veri okumayı geçmez ConnectionInfo en inputStream gibi görünüyor (bile daha önce söylediği gibi, hiçbir istisnası atılır) .
Bu hatayı, bağlantı yaparken yuvaları kapatarak, bağlantıyı kapatırken, el sıkışma yapılırken kurulan bağlantıları öldürmek için conntrack kullanarak, bu yüzden herhangi bir yardım YÜKSEK takdir edildim .
:String ident = new IdentificationStringParser(buffer, loggerFactory).parseIdentificationString();
if (ident.isEmpty()) {
return ident;
}
IdentificationStringParser.parseIdentificationString() boş bir dize döndürür, bu arayanın yöntemine iade edilecektir:)
'waitForServerIdent' bayrağını true olarak ayarlamayı denediniz mi? Bağlandığınız SSH sunucu türü nedir? –
İplik dökümü araştırdınız mı? –
Hiery Nomus: Siparişi ve bir SFTP sunucusunu değiştirirken bir fark yok. :) Vladislav: İş parçacığı dökümü, söz konusu bölümde bir kilitlenme gösteriyor: sunucudan yanıt alınmıyor, bu nedenle program sonsuza dek durdu ... kod sorunu değil. –