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.
komunikacija sa serverom
Zaključano
Zakačeno
Pretpostavljam da ti niko nece moci pomoci bez parceta tvog konkretnog koda...
izmenjeno 1 put, poslednji put itf 10.09.2005. u 09:37
Izmene poruke
- itf10.09.2005. u 09:37zapis iz teksta poruke
Evo, baš sam nešto radio u vezi toga prethodnih dana... SERVER-KLIJENT komunikacija:
SERVER.CPP
------------
KLIJENT.CPP
-----------
Ovo sam radio za jedan predmet na faksu pa ćeš dosta toga moći i eliminirati :)
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;
}
#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);
}
#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 :)
Hvala itf na kodu, vidim da si to ostvario preko stream klijenta i servera, mozda bi to pomoglo.
Code:
// ...
char buf[1000];
// ...
if( recv(sock, buf, 1024,0)<0 )
// ...
// ...
char buf[1000];
// ...
if( recv(sock, buf, 1024,0)<0 )
// ...
1000 < 1024 ?
Mozda neki #define BUFF 1000
izmenjeno 1 put, poslednji put itf 10.09.2005. u 09:53
Izmene poruke
- itf10.09.2005. u 09:53zapis iz teksta poruke
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
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
Ma naravno, salim se ;)
itf:
Imas TClientSocket i TServerSocket kod Borland C++ Builder-a...
itf:
Imas TClientSocket i TServerSocket kod Borland C++ Builder-a...
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
Radi, radi ;)
Cucemo se, imam svoj kod... Neki serveri koje sam uradio rade evo vec 4-ta godina
bez problema...
Cucemo se, imam svoj kod... Neki serveri koje sam uradio rade evo vec 4-ta godina
bez problema...
izmenjeno 1 put, poslednji put itf 10.09.2005. u 10:05
Izmene poruke
- itf10.09.2005. u 10:05zapis iz teksta poruke
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?
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...
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...
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.
Moze i tako...
Inace, uza specijalnost su mi serveri:
Servisna aplikacija + client/server komponente...
... pa ako ti zatreba tu sam.
Inace, uza specijalnost su mi serveri:
Servisna aplikacija + client/server komponente...
... pa ako ti zatreba tu sam.
izmenjeno 1 put, poslednji put insomniac_st 12.09.2005. u 11:50
Izmene poruke
- insomniac_st12.09.2005. u 11:50zapis iz teksta poruke
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 ...)
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! #
######################
# Zivio mi ti 100 godina rodjo! #
######################
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...
\ . . . 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...
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?
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! #
######################
# Zivio mi ti 100 godina rodjo! #
######################
Jesi pogledao one gore linkove?
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
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
@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:(
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! #
######################
# Zivio mi ti 100 godina rodjo! #
######################
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.