2016-03-17 5 views
2

Я пытаюсь создать и поддерживать TCP-соединение с хостом из автономного приложения Java.Ошибка соединения с ошибкой: ошибка записи сокета. Что не так с моим кодом Java

Порт локального порта и сервера тот же = 8999. После подключения, я должен отправить сообщение с сервера на сервер: <STX>username=fred&password=abcd<ETX>.

Код для создания сокета и отправки сообщений выглядит:

Socket socket = new Socket("mshxml.abcd.com", 8999, InetAddress.getLocalHost(), 8999); 
OutputStream outStream = socket.getOutputStream(); 
while (socket.isConnected()) { 
    try { 
     int stx = 2, etx = 3; 
     DataOutputStream dout = new DataOutputStream(outStream); 
     dout.writeByte(stx); 
     dout.writeBytes("username=fred&password=abcd"); 
     dout.writeByte(etx); 
    } catch (Exception e) { 
     e.printStackTrace(); 
} 

Но связь не сохраняется. На отладку, я нахожу следующее сообщение об ошибке:

java.net.SocketException: Connection reset by peer: socket write error 
     at java.net.SocketOutputStream.socketWrite0(Native Method) 
     at java.net.SocketOutputStream.socketWrite(Unknown Source) 
     at java.net.SocketOutputStream.write(Unknown Source) 
     at java.io.DataOutputStream.writeBytes(Unknown Source) 
     at com.voya.socketprog.CClient.createConnection(CClient.java:120) 
     at com.voya.socketprog.CClient.createSocket(CClient.java:33) 
     at com.voya.socketprog.CClient.main(CClient.java:138) Line 120 is: dout.writeBytes("username=fred&password=abcd"); 

Примечание: Эта же программа работает успешно при подключении к серверу (фиктивной LOCALHOST) на моей машине, где я в состоянии принимать и отправлять сообщения.

Пожалуйста, помогите.

+0

«Порт локального порта и сервера тот же = 8999» Почему? – EJP

ответ

0
while (socket.isConnected()) { 

Проблема здесь.

  1. Там нет причин для while петли в первую очередь. Это сообщение для входа: его нужно отправить только один раз. Сервер почти наверняка не ожидает второго от подключенного входа, поэтому он закрывается.

  2. isConnected() недействительный тест для подключения все еще присутствует. Единственным допустимым тестом является отсутствие IOException, например, тот, который вы получаете, что означает, что сверстник закрыл соединение. И когда вы получаете такое исключение, все, что вы можете сделать, это закрыть сокет и перестать пытаться. Повторная попытка бессмысленна: соединение прошло.

Socket.isConnected() только говорит вам о состоянии гнезда. Не соединение. Вы подключили этот разъем, поэтому он подключен.

NB Вы должны использовать одни и те же потоки для жизни сокета, а не создавать новые сообщения.

+0

Я удалил строки «while» и «Socket.isConnected()». Тем не менее, я столкнулся с той же ошибкой в ​​строке 'dout.writeBytes ("username = fred & password = abcd"); , В основном я столкнулся с этой ошибкой всякий раз, когда я пытаюсь написать второй раз в «dataoutputstream». (если я удалю эту конкретную строку, ошибка придет в следующей строке, т.е.когда я пишу ETX) @EJP – Pratap

+0

Если это действительно так, ваша идея протокола приложения неверна. Одноранговый узел не распознает даже STX. Но мне очень трудно поверить. Недостаточно времени между отправкой STX и второй строкой для того, чтобы одноранговый узел получил STX и закрыл сокет, а ваш хост получил закрытие перед отправкой второй строки. Вы посылаете что-то еще недействительное заранее? – EJP

-1

@EJP @weston Проблема решена после большого количества ударов & проб. Рабочий код выглядит следующим образом:

Socket socket = new Socket("mshxml.abcd.com", 8999, InetAddress.getLocalHost(), 8999); 
OutputStream outStream = socket.getOutputStream(); 

    try { 
    String STX = new Character((char) 2).toString(); 
    String ETX = new Character((char) 3).toString(); 
    OutputStreamWriter osw = new OutputStreamWriter(outStream); 
    BufferedWriter bw = new BufferedWriter(osw); 

    bw.write(STX + "username=fred&password=abcd" + ETX); 
    bw.flush(); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

Но у меня нет идеи, почему этот код работает, а оригинала не было. Любые предложения будут высоко ценится. И большое спасибо за опору с моими запросами и дублирующими сообщениями. :)

@EJP относительно вашей мысли о том, что сервер закрывает соединение между получением STX и следующей строкой, вы правы. Сервер не сразу закрыл соединение; это было только во время отладки (когда серверу было достаточно времени для анализа байтов), что я заметил, что это так.

+0

Этот код не работает. Вы не будете убеждать меня, что сервер ожидает бесконечное количество строк входа, а тест 'isConnected()' остается недопустимым. Вы изменили что-то еще. – EJP

+0

в то время как заявление было добавлено по ошибке здесь. Обновлен код. – Pratap

+0

И теперь вы не будете убеждать меня, что код «DataOutputStream» в исходной версии не работает, как только вы удалили цикл. «Писатели» не предназначены для двоичных данных. – EJP