Интерактивный Telnet

pnp2000
Offline
Зарегистрирован: 05.12.2013

Вот стоит задача интерактивной работы с Telnet, нужно общатся с почтовым серваком и посылать запросы в зависимости от того что скажет сервак, как это лучше реализовать, делаю вызов функции

byte sendEmail()
{
  if (client.connect(server, 25)) {
    Serial.println("connected");
  } else {
    Serial.println("connection failed");
    return 0;
  }
сhar c = client.read();
    Serial.print(c);
}

Приблизительно вот так это выглядит, но в терминал возвражается только символ "ÿ"

 

maksim
Offline
Зарегистрирован: 12.02.2012

pnp2000 пишет:

возвражается только символ "ÿ"

Это потому что вы не проверяя наличее данных в буфере читаете пустой буфер.

pnp2000
Offline
Зарегистрирован: 05.12.2013

ну добавляю 

if (client.available()) {}

 

ничего не меняется, точнее вобще ничего не выплёвывает, хотя если соеденятся телнетом то при подключении текстовые данные сервак отдаётся

maksim
Offline
Зарегистрирован: 12.02.2012

Ну так значит ничего нет.

pnp2000 пишет:

хотя если соеденятся телнетом то при подключении текстовые данные сервак отдаётся

Чаво?

pnp2000
Offline
Зарегистрирован: 05.12.2013

maksim пишет:

Ну так значит ничего нет.

pnp2000 пишет:

хотя если соеденятся телнетом то при подключении текстовые данные сервак отдаётся

Чаво?

Ну когда я цепляюсь к серваку телнетом то после установления соеденения сервак отдаёт достаточно большой ответ о готовности работы, ну там тип сервера и т.д. , то есть после соеденения в буфере что-то должно остатся

 

вот сделал так

byte sendEmail()
{
  if (client.connect(server, 25)) {
    Serial.println("connected");
  } else {
    Serial.println("connection failed");
    return 0;
  }
  delay(2000);
  client.write("EHLO SERVERNAME");
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
}

в итоге в буфере тишина, хотя при запросе серверу: EHLO SERVERNAME он должен дать либо ошибку либо отдать нормальные данные.

maksim
Offline
Зарегистрирован: 12.02.2012

http://arduino.ru/forum/programmirovanie/plata-uhf-rfid-reeder-dannye-po-wiegand#comment-49548

byte sendEmail()
{
  if (client.connect(server, 25)) 
    Serial.println("connected");
  else 
  {
    Serial.println("connection failed");
    return 0;
  }
  client.println("EHLO SERVERNAME");
  delay(3000);
  while(client.available())
  {
    char c = client.read();
    Serial.print(c);
  }
}

 

pnp2000
Offline
Зарегистрирован: 05.12.2013

Спасибо за наводку, всё вышло, оказывается ардуино получает ответ значительно медленнее чем его видно через Telnet, увеличил ожидание и весь вывод получился в терминале, ктож знал что нужно аж до 6сек повышать ожидание, я уж думал код кривой, осталось разобратся как его парсить быстрее и обработчик почты будет готов

maksim
Offline
Зарегистрирован: 12.02.2012

Можно организовать "побайтное" ожидание.

maksim
Offline
Зарегистрирован: 12.02.2012

Примерно так:

byte sendEmail()
{
  if (client.connect(server, 25)) 
    Serial.println("connected");
  else 
  {
    Serial.println("connection failed");
    return 0;
  }

  client.println("EHLO SERVERNAME");
  delay(300); // Немного подождем чтобы сервер успел отреагировать
  bool timeout = 0;
  while(!timeout)
  {
    uint32_t time = millis();
    while(!client.available() && millis()-time < 100);
    if(client.available())
    {
      char c = client.read();
      Serial.print(c);
    }
    else timeout = 1;
  }
}

 

pnp2000
Offline
Зарегистрирован: 05.12.2013

Спасибо, попрорбую, сейчас столкнулся с новой проблемой, поиск совпадений в ответах сервера, нужно найти в строчку нужное число, еапример 200, вот уж недумал что ньюансы будут на кадом шагу поджидать.

toc
Offline
Зарегистрирован: 09.02.2013

это не нюансы, это обычное программирование. Попробуйте изучить мировой опыт по теме https://www.google.com/search?q=arduino+smtp+ethernet

Нюансы начнуться, когда

* сервер попросит аутентифицироваться нетривиальным способом

 * вы захотите получить отправленное вами же сообщение, которое почему-то считается всеми посредниками нвтуральным Спамом

pnp2000
Offline
Зарегистрирован: 05.12.2013

Может кто-то будет задаваться таким же вопросом, вот хорошая ссылка http://jeremylaurenson.wordpress.com/2012/05/28/ardueno-smtp-code/ , пароль и логин кодируются в любом on-line base64 конвертере, например тут http://base64.ru/

if (client.connect("smtp.yourisp.com", 25)) {
  boolean ok=true;
  Serial.println("connected...");
  ok=readInternetLineContining("220 ",5);

  if(ok){
    client.println("ehlo arduino.yourname.com");
    ok=readInternetLineContining("250 ",5);
  }

  if(ok){
    client.println("AUTH PLAIN [[[YOUR BASE64 AUTH STRING HERE]]]");
    ok=readInternetLineContining("235 ",5);
  }

  if(ok){
    client.println("MAIL FROM:<jeremy@laurenson.com>");
    ok=readInternetLineContining("250 ",5);
  }

  if(ok){
    client.println("RCPT TO:<pagejeremy@laurenson.com>");
    ok=readInternetLineContining("250 ",5);
  }

  if(ok){
    client.println("DATA");
    ok=readInternetLineContining("354 ",5);
  }

  if(ok){
    client.println("From: <user@ardueno.com>");
    client.println("TO: <pagejeremy@ardueno.com>");
    client.println("SUBJECT: Your page, sir...");
    client.println();
    client.println("This from Arduino");
    client.println(".");
    ok=readInternetLineContining("250 ",5);
  }

  if(ok){
    client.println("QUIT");
    ok=readInternetLineContining("221 ",5);
  }

  if(ok){
    Serial.println("done with success!");
  }

  client.stop();

}
else {
  Serial.println("connection failed");
}

boolean readInternetLineContining( String search, int timeOut)
{
 time_t t=now();
 boolean found=false;
 String tempString;

 Serial.println("Looking for " + search + " in the Ethernet stream...");

 while(!found){
  tempString =readInternetLine(timeOut);
  Serial.println(tempString);
  if(tempString.indexOf(search)>-1)
  {
    Serial.println("Found!");
    return true;
   }

  if(now()-t>timeOut){
    Serial.println("Timeout looking for "+ search);
    return false;
   }
  }
}

String readInternetLine(int timeOut)
{
// This function reads a line of text from the network client connection.
// and returns after a \r\n (It does not return the \r or \n)
// It also only waits for timeOut number of seconds before returning, assuming
// that the return string never came.

if(!client.connected())return "";
time_t t=now();
int ok=0;
String tempString="";
while(ok==0){
if(client.available()) {
char c = client.read();
if(c=='\n')ok=1;
if(!(c=='\r'))if(!(c=='\n'))
tempString.concat(c);
}
else
{
if(now()-t>timeOut)ok=1;
}
}
return(tempString);
}

Авторизация PLAIN лично у меня не заработала, перла нету , а онлайн несмог сгенерировать строчку которая бы работала, поэтому логонился через AUTH LOGIN, то есть вот так

if(ok){
    client.println("ehlo arduino.yourname.com");
    ok=readInternetLineContining("250 ",5);
  }

if (ok) {
      client.println("AUTH LOGIN");
      ok = readInternetLineContining("334 ", 5);
    }
    if (ok) {
      client.print("login");   // Login in BASE64
      ok = readInternetLineContining("334 ", 5);
    }

    if (ok) {
      client.print("password");  // password in base64
      ok = readInternetLineContining("235 ", 5);
    }

  if(ok){
    client.println("MAIL FROM:<jeremy@laurenson.com>");
    ok=readInternetLineContining("250 ",5);
  }