[C/C++, Linux, Socket] Problem z recv ()

0

Witam,

Jestem świeży w pisaniu aplikacji sieciowych. Mam do napisania aplikację kliencką która będzie pobierała dane z serwera w formie XML, ale już na samym początku utknąłem. W ramach treningu napisałem sobie taki bardzo prymitywny program na podstawie jakiegoś tutoriala:

/*test1.c*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define MSG_LEN 512

int main(void) {
printf ("TEST0!"); 
 int s, result;
  struct sockaddr_in taddr;
	char msg [MSG_LEN];

  /*tworzymy gniazdko*/
  s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (s < 0) {
    perror("socket");
    return 1;
  }

  /*zerujemy strukture adresowa*/
  memset(&taddr, 0, sizeof(struct sockaddr));

  /*wypelniamy strukture adresem docelowym*/
  taddr.sin_family = AF_INET;
  taddr.sin_port  = htons(80XX);//tu podaję port
  taddr.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx");//tu podaję ip serwera
printf ("TEST1!");
  /*laczymy sie z serwerem*/
  result = connect(s, (struct sockaddr*)&taddr, sizeof(struct sockaddr));
  if (result < 0) {
    close(s);
    perror("connect");
    return 1;
  }


/*w tym miejscu mozemy juz zaczac wymieniac dane z komputerem*/
memset (msg, 0, MSG_LEN);
result=send(s, "Tekst do wysłania", 25, 0);
if (result < 0) 
{
    close(s);
    printf("Bug przy wysyłaniu!");
    return 1;
}
  printf("Poszlo!");

result=recv (s, msg, MSG_LEN, 0);
if (result < 0) 
{
    close(s);
    printf("Bug przy odbiorze!");
    return 1;
}
printf ("Liczba odczytanych bajtow: %d", result);	
	
  /*zamykamy gniazdko*/
  close(s);
  return 0;
} 

W momencie, gdy do kodu fragment z recv () program w ogóle nie działa - po odpaleniu jakby się zawiesza. Nawet nie wyświetlają się te teksty "TEST". Gdy nie ma tego fragmentu, to wygląda, że łączy się i wysyła prawidłowo. O co chodzi? Bardzo proszę o pomoc.

0

A czy przypadkiem recv() nie jest funkcją blokującą ? A jeśli Ci sie nie wyswietlaja teksty "TEST0", itp, to sprobuj wypisywac: printf("TEST0\n");

0

Dzięki! Z tymi \n rzeczywiście miałeś rację.

Mimo wszystko serwer nadal nic mi nie odsyła:( Zakładając, że działa on prawidłowo, jakie mogą być jeszcze tego przyczyny?

0

A może takie dziwne zachowanie wynika z faktu, że połączenie używa kanały szyfrowanego z SSL czy TLS? Jest to możliwe:/??

0

Jestes pewien, ze serwer otrzymuje to, co mu wysłałeś ? I czy odpowiada na to ? Bo jeśli recv() jest blokujące, to czeka, az serwer mu odpowie. A jesli nie odpowiada, to Twoj program czeka na odpowiedz, ktora nie nadchodzi...

0

jeśli serwer odpowiada, to program się zamyka od razu, bo nigdzie zatrzymujesz go, po recvie
jeśli serwer nic nie odpowiada, to program wisi na recv

jakie objawy są u ciebie?

0

Program wisi na recv .
Kiedy sprawdzam, czy łączenie i wysyłanie zakończyło się błędem (zwróceniem -1) to wygląda na to, że te operacje zakończyły się sukcesem. Ale rozumiem, że zakończenie senda nie błędem, oznacza tylko tyle, że udało się wysłać ode mnie pakiety, a nie, że serwer do którego wysyłałem je odebrał?
Jak już powiedziałem, ja jestem w kwestii programowania socketów bardzo początkujący, również z zagadnień sieciowych nie jestem orzeł, także do głowy przychodzą mi takie problemy:

  1. Nie wiem ilu bajtów spodziewa sie serwer w każdej wysłanej wiadomości - czy to może być problemem? Już wysyłałem wiadomości o bardzo dużym rozmiarze, ale to nie pomogło.
  2. Wiem, że serwer używa jakiegoś szyfrowania kanału - w specyfikacji mam podane, żę po nawiązaniu połączenia (co się udaje) serwer czeka na dane do logowania, które potwierdza, lub zwraca że są do kitu. Z tego rozumiem, że nawet jak poślę dane niezaszyfrowane, to powinien mi odpowiedzieć, że dane nie są dobre, nie?

Proszę o poradę:)

0
  1. Wiem, że serwer używa jakiegoś szyfrowania kanału - w specyfikacji mam podane, żę po nawiązaniu połączenia (co się udaje) serwer czeka na dane do logowania, które potwierdza, lub zwraca że są do kitu. Z tego rozumiem, że nawet jak poślę dane niezaszyfrowane, to powinien mi odpowiedzieć, że dane nie są dobre, nie?
    Szyfrowanie a autoryzacja to dwie osobne sprawy.

Musisz przesłać dane zgodnie z protokołem. Inaczej serwer nie zagada. Serwer ma odpowiedzieć czy dane do logowania są ok, więc pytanie czy poprawnie wysłałeś dane do zalogowania ? Na pewno oczekuje specjalnego formatu typu "USER xxx\0PASS yyy\0", albo po prostu "xxx\0yyy\0".

Skoro jest mowa o szyfrowaniu, to te dane też muszą być zaszyfrowane. I teraz pytanie jakiego protokołu do szyfrowania masz użyć ? Wszystko powinno być w specyfikacji.

Dopiero jak serwer dostanie dane w formacie który potrafi zinterpretować to coś odpowie.

0

Czuję, że zmierzamy w dobrym kierunku:) Dzięki wielkie!

Wiem w jakim formacie chce serwer dostać dane do zalogowania (mam przykładowy dokument w XML odpowiednio pokomentowany). Widzę też, że serwer komunikuje się poprzez kanał z protokołem TLS. Tylko widzę w opisie tego protokołu, że serwer powinien posiadać klucz. Czy ja go nie powinienem znać?

Czyli przed wysłaniem danych nadaję temu stringowi który chcę wysłać, taki format aby odpowiadał temu z przykładowego dokumentu XML, a następnie taki ciąg szyfruję TLS i wysyłam? Dobrze skumałem, czy coś pzesadnie uprościłem?

0

Nie pisałem klienta z użyciem TLS, ale najpewniej trzeba będzie użyć jakiejś gotowej biblioteczki która dba o wszystko (wymiana kluczy, szyfrowanie ...) i używać jak zwykły socket.

0

Ok, dzięki! Biorę się za poszukiwania biblioteki:)
Mam nadzieję, że dam radę się z tym uporać! Jeżeli ktoś ma sugestie czego użyć itp to chętnie wysłucham

1 użytkowników online, w tym zalogowanych: 0, gości: 1