Сетевое программирование в C# (Клиент Telnet)
От: quadgod  
Дата: 12.04.10 09:10
Оценка:
Есть обыкновенная сетевая служба (Abacs биллинг). Соединяюсь с ней по telnet пишу различные сообщения, а она мне отвечает (Все прекрасно работает по telnet). Стоит задача написать WebService на asp.net для данной службы. Когда начинается socket.Receive программа зависает. Причем, не зацикливается в цикле, а именно виснет в момент получения первой порции данных.

Уважаемые гуру сетевого программирования .NET, скажите, что я делаю не так?
Неработающий код:


public static string GetResponse(string req)
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(config.ip, config.port);
int bytes = 0;
string resp = string.Empty;
byte[] buffer = new byte[256];
byte[] bytesReq = Encoding.ASCII.GetBytes("HELLO");
bytes = socket.Send(bytesReq, bytesReq.Length, SocketFlags.None);
if (socket.Connected)
{
do
{
bytes = socket.Receive(buffer, buffer.Length, SocketFlags.None);
resp += Encoding.ASCII.GetString(buffer);
}
while(bytes > 0);
}
socket.Close();
return resp;
}


Попробовал написать на java все работает, причем идеально:

public synchronized StringBuilder request(String request) throws OpenSocketException, TimeoutConnectException, CloseSocketException {
Socket clientSocket = new Socket();
Scanner in;
PrintWriter out;
StringBuilder result = new StringBuilder();
try {
clientSocket.connect(new InetSocketAddress(HOSTNAME, PORT), CONNECT_TIMEOUT);
out = new PrintWriter(clientSocket.getOutputStream());
in = new Scanner(clientSocket.getInputStream(), "Cp1251");
clientSocket.setSoTimeout(RECEIVE_TIMEOUT);
out.print(request);
out.flush();
try {
clientSocket.shutdownOutput();
} catch (IOException ex) {
throw new CloseSocketException(ex.getLocalizedMessage());
}
while (in.hasNextLine()) {
result.append(in.nextLine());
}
} catch (SocketException ex) {
throw new TimeoutConnectException(ex.getLocalizedMessage());
} catch (IOException ex) {
throw new OpenSocketException(ex.getLocalizedMessage());
} finally {
try {
clientSocket.close();
} catch (IOException ex) {
throw new CloseSocketException(ex.getLocalizedMessage());
}
}
return result;
}
Re: Сетевое программирование в C# (Клиент Telnet)
От: matumba  
Дата: 12.04.10 09:28
Оценка:
Здравствуйте, quadgod, Вы писали:

Q>Когда начинается socket.Receive программа зависает. Причем, не зацикливается в цикле, а именно виснет в момент получения первой порции данных.


Возможно, данные не были даже отправлены. Я делал через NetworkStream + Flush после каждой посылки — работает.
Re[2]: Сетевое программирование в C# (Клиент Telnet)
От: quadgod  
Дата: 12.04.10 09:41
Оценка:
Здравствуйте, matumba, Вы писали:

M>Здравствуйте, quadgod, Вы писали:


Q>>Когда начинается socket.Receive программа зависает. Причем, не зацикливается в цикле, а именно виснет в момент получения первой порции данных.


M>Возможно, данные не были даже отправлены. Я делал через NetworkStream + Flush после каждой посылки — работает.

Делаю StreamReader из нетстрима. При чтении тоже виснет.
Re: Сетевое программирование в C# (Клиент Telnet)
От: Jolly Roger  
Дата: 12.04.10 09:42
Оценка: 1 (1)
Здравствуйте, quadgod, Вы писали:

А так?

byte[] bytesReq = Encoding.ASCII.GetBytes("HELLO\r\n");
"Нормальные герои всегда идут в обход!"
Re[2]: Сетевое программирование в C# (Клиент Telnet)
От: quadgod  
Дата: 12.04.10 09:54
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, quadgod, Вы писали:


JR>А так?


JR>byte[] bytesReq = Encoding.ASCII.GetBytes("HELLO\r\n");


Заработало!!! Почему именно так?
Re[3]: Сетевое программирование в C# (Клиент Telnet)
От: Jolly Roger  
Дата: 12.04.10 10:03
Оценка:
Здравствуйте, quadgod, Вы писали:

Q>Заработало!!! Почему именно так?


Ну а как сервер иначе определит, что он получил весь запрос целиком? Нет у него другого способа, кроме как отправка клиентом маркера конца запроса, каковым в большинстве текстовых протоколов и является комбинация CR+LF == "\r\n"
"Нормальные герои всегда идут в обход!"
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.