Novo

Forum kao aplikacija na telefonu

Dodajte forum na početni ekran i koristite ga kao aplikaciju, sa menijem na dnu ekrana.

  • 23 odgovora
  • 6.936 pregleda

Najnovija ↓

komunikacija sa serverom 10.09.2005. u 09:19 · pre 257 meseci #1
Pisem klijentsku aplikaciju u C-u koja treba slati upite serveru koji ce na njih odgovarati. Napravio sam neki privremeni spremnik tipa char buffer [100] preko kojega saljem upite. Medutim, server ne odgovara kako bi trebao jer ponekad samo napravi echo tj. vrati ono sto sam poslao. Pokusao sam sa dva buffera, jedan za slanje a drugi za primanje i opet imam slicnu stvar. U cemo moze biti problem, sa kojim pristupom bi jos mogao pokusati? Napominjem da serverski kod ne smijem mijenjati.
Re: komunikacija sa serverom 10.09.2005. u 09:32 · pre 257 meseci #2
Pretpostavljam da ti niko nece moci pomoci bez parceta tvog konkretnog koda...

Re: komunikacija sa serverom 10.09.2005. u 09:33 · pre 257 meseci
izmenjeno 1 put, poslednji put itf 10.09.2005. u 09:37
  1. itf10.09.2005. u 09:37zapis iz teksta poruke
#3
Evo, baš sam nešto radio u vezi toga prethodnih dana... SERVER-KLIJENT komunikacija:

SERVER.CPP
------------
Code:
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>

struct student{
    char ime[20];
    char prez[20];
    char matbr[15];
    char JMBG[15];
    short kz1;
    short kz2;
    short lab;
    float ukupno;
    short ocjena;
};

//treba linkati sa Ws2_32.lib
void win32stuff(){
    WSADATA wsaData;

    if(WSAStartup(MAKEWORD( 2, 2 ), &wsaData)){
        fprintf(stderr, "Ne mogu inicijalizirati mrezu\n");
        exit(1);
    }

    if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) {
        /* Tell the user that we could not find a usable */
        /* WinSock DLL.                                  */

        fprintf(stderr, "Ne mogu inicijalizirati prave parametre\n");
        WSACleanup( );
        exit(1);
    }
}


int main(){
    int sock, lenght, bodovi = 0, ocjena = 0;
    struct sockaddr_in name, client;
    char buf[1000];

    win32stuff();

    sock=socket(AF_INET, SOCK_DGRAM, 0);
    
    if( sock<0 ){
        perror("Nece stvoriti socket\n");
        exit(1);
    }
    
    name.sin_family = AF_INET;
    name.sin_addr.s_addr = INADDR_ANY;
    name.sin_port=htons(10000);
    
    if( bind(sock, (struct sockaddr*) &name, sizeof(name) )<0 ){
        perror("Nece bindati\n");
        exit(1);
    }
    
    lenght=sizeof(name);
    
    if(getsockname(sock, (struct sockaddr*) &name, &lenght)<0){
        perror("Getsocket error\n");
        exit(1);
    }
    
    printf("Socket je na portu: %d, ja slusam:\n", ntohs(name.sin_port));
    
    while(1){
        if( recvfrom(sock, buf, 1024,0, (struct sockaddr*) &client, &lenght)<0 )
            perror("Nece ili nema sto za citati\n");
        else{
            printf("=>%s\n", buf);
            bodovi = 0;
            ocjena = 0;
                                      // obradi dobivene podatke
            // Rezultati(buf, &bodovi, &ocjena);
            sprintf(buf, "%s %d %d\n", buf, bodovi, ocjena);
            if( sendto(sock, buf, strlen(buf)+1, 0, (struct sockaddr*) &client, sizeof(name))<0 ){
                perror("Nece slati\n");
                exit(1);
            }
        }
        
        if(buf[0]=='e' && buf[1]=='n' && buf[2]=='d')
            break;
    }
    closesocket(sock);
    return 0;
}


KLIJENT.CPP
-----------
Code:
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>

//treba linkati sa Ws2_32.lib
void win32stuff(){
    WSADATA wsaData;

    if(WSAStartup(MAKEWORD( 2, 2 ), &wsaData)){
        fprintf(stderr, "Ne mogu inicijalizirati mrezu\n");
        exit(1);
    }

    if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) {
        /* Tell the user that we could not find a usable */
        /* WinSock DLL.                                  */

        fprintf(stderr, "Ne mogu inicijalizirati prave parametre\n");
        WSACleanup( );
        exit(1);
    }
}

void main(int argc, char *argv[]){
    int sock;
    struct sockaddr_in name;
    struct hostent *hp;
    char buf[1000];
    
    win32stuff();

    sock=socket(AF_INET, SOCK_DGRAM, 0);
    
    if(argc<4){
        perror("Upotreba: program racunalo port poruka\n");
        getchar();
        exit(1);
    }
    if( sock<0 ){
        perror("Nece stvoriti socket\n");
        exit(1);
    }
    
    hp=gethostbyname(argv[1]);
    
    if(hp==0){
        perror("%s - nepoznat host!\n");
        exit(1);
    }
    
    memcpy ( (char*) &name.sin_addr, (char*)hp->h_addr, hp->h_length);
    
    name.sin_family = AF_INET;
    name.sin_port=htons(atoi(argv[2]));
    
    if( sendto(sock, argv[3], strlen(argv[3])+1, 0, (struct sockaddr*) &name, sizeof(name))<0 ){
        perror("Nece slati\n");
        exit(1);
    }
    if( recv(sock, buf, 1024,0)<0 )
        perror("Nece ili nema sto za citati\n"); 
    else 
        printf("=>%s\n", buf);  

    closesocket(sock);
}


Ovo sam radio za jedan predmet na faksu pa ćeš dosta toga moći i eliminirati :)
Re: komunikacija sa serverom 10.09.2005. u 09:47 · pre 257 meseci #4
Hvala itf na kodu, vidim da si to ostvario preko stream klijenta i servera, mozda bi to pomoglo.
Re: komunikacija sa serverom 10.09.2005. u 09:48 · pre 257 meseci #5
Code:

// ...
char buf[1000];
// ...
if( recv(sock, buf, 1024,0)<0 )
// ...


1000 < 1024 ?

Mozda neki #define BUFF 1000
Re: komunikacija sa serverom 10.09.2005. u 09:50 · pre 257 meseci
izmenjeno 1 put, poslednji put itf 10.09.2005. u 09:53
  1. itf10.09.2005. u 09:53zapis iz teksta poruke
#6
Ma sad sam tu nešto brisao jer je bila hrpa nepotrebnih stvari pa je i to nestalo. Uostalom, ako se već čovjek bavi tim stvarima to mu je najmanji problem ;)

Evo tu je opisano mnogo detaljnije

http://www.zemris.fer.hr/~leonardo/mreze/umr/lab6/vjezba6.htm
http://www.zemris.fer.hr/~leonardo/mreze/umr/lab7/vjezba7.htm
Re: komunikacija sa serverom 10.09.2005. u 09:55 · pre 257 meseci #7
Ma naravno, salim se ;)

itf:
Imas TClientSocket i TServerSocket kod Borland C++ Builder-a...



Re: komunikacija sa serverom 10.09.2005. u 09:58 · pre 257 meseci #8
TO NE RADI! Baš me naživciralo jer stalno puca program koji sadži te komponente. Izgleda da su outdated. Ajd javi ako tebi to radi. Imaš gotov primjer u examples direktoriju
Re: komunikacija sa serverom 10.09.2005. u 10:02 · pre 257 meseci #9
Radi, radi ;)

Cucemo se, imam svoj kod... Neki serveri koje sam uradio rade evo vec 4-ta godina
bez problema...


Re: komunikacija sa serverom 10.09.2005. u 10:05 · pre 257 meseci
izmenjeno 1 put, poslednji put itf 10.09.2005. u 10:05
  1. itf10.09.2005. u 10:05zapis iz teksta poruke
#10
Meni pukne kada pošaljem drugu poruku. Još prva je OK, ali već na drugoj puca. A ništa.... Valjda je nešto do OS-a.. Baš si pokušao na 127.0.0.1? Onaj CHAT primjer?
Re: komunikacija sa serverom 10.09.2005. u 10:11 · pre 257 meseci #11
Problem kod skoro svih primera koji se bave socket-ima je sto polaze od
pretpostavke da ce CEO BUFFER biti poslat ODJEDNOM sto je nedospustivo
sa stanovista TCP/IP protokola.

Najgore je sto takvi primeri zaista (u startu) i prorade jer se radi najcesce
o jednoj te istoj masini gde je i klijent i server, i sto se radi o zaista malim
kolicinama podataka poslatim u 'laboratorisjkim' uslovima.

U praksi to puca 100%.

Dakle, gluposti tipa SendText() / ReceiveText() su samo za izlozbu a ne i za
ozbiljan rad.

Dakle, klijent treba da pokusa slanje:

1) celog buffera ili
2) nekog obranicenog buffera da '8192' bajta

... onda se ocitava povratna vrednost KOLIKO je zaista bajtova poslato, pa se
odatle i nastavlja, itd...

kod servera je slicno, cita se koliko je primljeno, i to se belezi u nekakab buffer.
Prethodno je JAKO PAMETNO da prva 4 bajta u protokolu budu UKUPNA DUZINA
buffera, itd...


Otom potom, cucemo se...

Re: komunikacija sa serverom 10.09.2005. u 10:18 · pre 257 meseci #12
Ma uopće se ne kanim sad time zafrkavati. Ako bude trebalo napravit ću ATL komponentu u .NET-u (ovo gore što sam napisao a radi) i registriram je u Borlandu.
Re: komunikacija sa serverom 10.09.2005. u 10:23 · pre 257 meseci #13
Moze i tako...

Inace, uza specijalnost su mi serveri:

Servisna aplikacija + client/server komponente...

... pa ako ti zatreba tu sam.
Re: komunikacija sa serverom 12.09.2005. u 11:48 · pre 257 meseci
izmenjeno 1 put, poslednji put insomniac_st 12.09.2005. u 11:50
  1. insomniac_st12.09.2005. u 11:50zapis iz teksta poruke
#14
Nisam uspio rijesit problem:(
Imam buffer tipa: char buffer [MAXDATASIZE]; (size je 100, nije to vazno,mislim)
saljem sa: gets(buffer); i send(create_socket,buffer, MAXDATASIZE ,0);
primam: recv( create_socket, buffer ,MAXDATASIZE,0); i puts(buffer)
Komunikacija je ostvarena, medutim u bufferu ponekad "nesto ostaje" pa mi server vrati dio poslanog zahtjeva sto ne bi smio.
socket je tipa: (create_socket = socket(AF_INET,SOCK_STREAM,0)
Mozda moze biti problem sto server prima sintaksu: \<nesto ovdje>/ jer je \ escape sekvenca...
(malo sam izmjesao logine, post je od milan82 ...)
Potpis
######################
# Zivio mi ti 100 godina rodjo! #
######################
Re: komunikacija sa serverom 12.09.2005. u 14:31 · pre 257 meseci #15
Cekaj, hoces da kazes da server 'prima' protokol u formatu:

\ . . . n e k i b u f f e r . . . /

... pri cemu je pocetak obrnuta kosa crta i kraj obicna kosa crta?

Ako je tako, pokazi kako si u programu smestio taj buffer... Moze se desiti da si sa
Escape-om unistio pocetak protokola...


Re: komunikacija sa serverom 12.09.2005. u 15:14 · pre 257 meseci #16
Da, naredbe su oblika \<naredba>/, i sad, ja sam pokusao sa gets (post ranije) i sa:

printf ("Unesi naredbu:");
scanf("%s", &naredba);
sprintf(buffer,"%s", naredba);
write (create_socket,buffer,100);
read (create_socket,buffer,100);
sscanf( buffer,"%s",&odgovor);
printf("\n%s\n",odgovor);

a imam char buffer[1024], char naredba[100] i char odgovor[100]

... i opet ne dobijem sto mi treba, imas kakvu ideju?


Potpis
######################
# Zivio mi ti 100 godina rodjo! #
######################
Re: komunikacija sa serverom 12.09.2005. u 18:22 · pre 257 meseci #18
Zar ne bi trebalo:

write (create_socket,naredba,strlen(naredba));


A za read se moras malo pomuciti.. tj. ne garantuje se da ces ceo pake dobiti odjednom (mada kratki paketici stizu u komadu), nego se moze desiti iz delova. Zato moras citati paketic po paketic i da sve to skupljas u neki "incoming" buffer. Posle svakog dodavanja u incoming buffer proveri da se u incoming bufferu nalaze cela komanda i tek je tada mozes izvrsiti.

Prilikom mrezne komunikacije obicno se na pocetku svakog paketa ubaci njegova duzina tako da onaj koji prima paket zna koliko bajtova moze da ocekuje.

yooyo
Re: komunikacija sa serverom 13.09.2005. u 12:36 · pre 257 meseci #19
@yooyo: Hvala, dosta mi je tvoj post pomogao, al opet ne znam kako to rjesiti. Napravio sam:

read (create_socket,buffer,sizeof(buffer));
sscanf( buffer,"%s",&odgovor);
int pp = strlen(odgovor);
printf ("\nodgovor size: %d",pp);

printf("\nodgovor: %s",odgovor);
(pokusao sam i sa strlen-om) Odgovor spremam u buffer, na izlazu dobijem da je duljina odgovora 4 a meni se prikaze ili nista ili djelic odgovora, znaci opet dobijem odgovor u dijelovima. Naravio sam:
do
{
read (create_socket,buffer,strlen(buffer));
}
while (strlen(buffer) > 2);

i opet nista.?

@itf: pogledao sam, nije pomoglo:(
Potpis
######################
# Zivio mi ti 100 godina rodjo! #
######################
Re: komunikacija sa serverom 13.09.2005. u 13:04 · pre 257 meseci #20
Citat:

read (create_socket,buffer,sizeof(buffer));
sscanf( buffer,"%s",&odgovor);
int pp = strlen(odgovor);
printf ("\nodgovor size: %d",pp);


Ovo ne treba da radis. read() vraca broj bajtova koji je stvarno procitao i stavio u buffer. Procitaj man read i ono sto je yooyo napisao.
Potpis
Never trust an operating system you don't have sources for.
Odgovori
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme