Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

TCP server na linuxu / multithread

Seznam témat     Nová odpověď

Přihlásit se     Registrace     Zapomenuté heslo

Re: TCP server na linuxu / multithread

Autor: hax0r

19:51:48 18.04.2009

Ses blahovej, jenom s tam mel tucet chyb. Skus to takhle, 100% overeno ;)

#include
#include
#include
#include
#include
#include
#include
#include
#include

int count = 0,size = 0;
sockaddr_in Server;
sockaddr_in Klient[32];
char ServerovyBuffer[32][1024];
int n,roura,klient[32];
socklen_t addrlen;
bool ukoncit[32];

pthread_t vlakna[32];
int pocet_vlaken = 0;
int cislo_klienta = 0;
pthread_attr_t nastavenivlakna;
typedef struct{

int cislo;
} parm;

parm pxp;


void *obsluha_klienta(void *pqxp){

parm *pxp = (parm *)pqxp;
int local_cislo_klienta = pxp->cislo;

ukoncit[cislo_klienta] = false;
printf("Klient %i : IP adresa ",local_cislo_klienta); printf(inet_ntoa((in_addr)Klient[local_cislo_klienta].sin_addr)); printf(".\n");

do{
for(int m = 0;m < 1023;m++)ServerovyBuffer[local_cislo_klienta][m] = 0;
if((size = recv(klient[local_cislo_klienta],ServerovyBuffer[local_cislo_klienta],1023,0)) <= 0){
ukoncit[local_cislo_klienta] = true;
}else{
printf("> %i klient vravi: ",local_cislo_klienta);printf(ServerovyBuffer[local_cislo_klienta]);

if((size = send(klient[local_cislo_klienta],"O dekuji za tva data.\n",23,0)) <= 0){
ukoncit[local_cislo_klienta] = true;
}}
}
while(!(ukoncit[local_cislo_klienta]));



printf("Klient %i se odpojil.\n",local_cislo_klienta);

pocet_vlaken--;
}


int main(void){
int port = 2875;
/*
gcvt(INADDR_ANY,10,ServerovyBuffer);
printf(ServerovyBuffer);
*/

if( (roura = socket(2,1,6)) == -1){
printf("Nelze vytvořit socket. Konec. \n");
return 8;
}

Server.sin_family = 2; // AF_INET
Server.sin_port = htons(port); // port serveru
Server.sin_addr.s_addr = 0; // jakakoli sitova karta


if( (bind(roura, (sockaddr *)&Server, sizeof(Server))) == -1){
printf("Problém s pojmenovanim socketu. Konec. \n");
return 16;
}

if(listen(roura,10) == -1){
printf("Problém s otevrenim fronty . Konec. \n");
return 32;
}

pthread_attr_init(&nastavenivlakna);

do{

addrlen = sizeof(Klient[0]);


klient[cislo_klienta] = accept(roura,(sockaddr *)&Klient[cislo_klienta],&addrlen);
// navazani spojeni
if(klient[cislo_klienta] <= 0){
printf("Chyba spojení.");
close(roura);
return (NULL);
}else{

pxp.cislo = pocet_vlaken;
pthread_create(&vlakna[pocet_vlaken++],&nastavenivlakna,obsluha_klienta,(void *)&pxp);
cislo_klienta++;
}}
while(++count <= 1024);
printf("Server byl ukončen.\n");

close(roura);
return 0;
}

Citovat příspěvek

 

Re: TCP server na linuxu / multithread

Autor: Matlák

11:31:11 07.12.2007

Normálně se to zkompiluje, pracuje to, ovšem jen s jedním klientem. To z tou nedotaženou logikou mezi proměnnými je zcela jasně pravda, i chování serveru tomu nasvědčuje,ještě si s tím nějak pohraju.

Citovat příspěvek

 

Re: TCP server na linuxu / multithread

Autor: Kojot

10:44:00 07.12.2007

Nezkousel jsem to prekladat, ale jak na to koukam, tak vidim aspon dva problemy.

1) No comment
[code]
if( (roura = socket(2,1,6)) == -1){
[/code]

2) Zda se mi nedotazena logika mezi promennymi pocet_vlaken a cislo_klienta. Po napojeni jednoho klienta dojde ke zvetseni promenne pocet_vlaken. Po napojeni druheho klienta je promenna cislo_klienta porad stejna a prepise se socket v poli klient[cislo_klienta]. Navic pole se v C/C++ indexuje od 0.

Citovat příspěvek

 

TCP server na linuxu / multithread

Autor: Matlák

10:09:37 07.12.2007

Dobrý den. Napsal jsem inspirován návodem zde na Builderu takovýto jednoduchý program jako základ linuxového TCP serveru :
[code]
#include
#include
#include
#include
#include
#include
#include
#include
#include

int count = 0,size = 0;
sockaddr_in Server;
sockaddr_in Klient[32];
char ServerovyBuffer[32][1024];
int n,roura,klient[32];
socklen_t addrlen;
bool ukoncit[32];

pthread_t vlakna[32];
int pocet_vlaken = 1;
int cislo_klienta = 1;
pthread_attr_t nastavenivlakna;
typedef struct{

int cislo;
} parm;

parm pxp;


void *obsluha_klienta(void *pqxp){

parm *pxp = (parm *)pqxp;
cislo_klienta = pxp->cislo;

ukoncit[cislo_klienta] = false;
printf("Klient %i : IP adresa ",cislo_klienta); printf(inet_ntoa((in_addr)Klient[cislo_klienta].sin_addr)); printf(".\n");

do{
for(int m = 0;m < 1023;m++)ServerovyBuffer[cislo_klienta][m] = 0;
if((size = recv(klient[cislo_klienta],ServerovyBuffer[cislo_klienta],1023,0)) <= 0){
ukoncit[cislo_klienta] = true;
}else{
printf(">");printf(ServerovyBuffer[cislo_klienta]);

if((size = send(klient[cislo_klienta],"O dekuji za tva data.\n",23,0)) <= 0){
ukoncit[cislo_klienta] = true;
}}
}
while(!(ukoncit[cislo_klienta]));



printf("Klient %i se odpojil.\n",cislo_klienta);

pocet_vlaken--;
}


int server(int port){
/*
gcvt(INADDR_ANY,10,ServerovyBuffer);
printf(ServerovyBuffer);
*/

if( (roura = socket(2,1,6)) == -1){
printf("Nelze vytvořit socket. Konec. \n");
return 8;
}

Server.sin_family = 2; // AF_INET
Server.sin_port = htons(port); // port serveru
Server.sin_addr.s_addr = 0; // jakakoli sitova karta


if( (bind(roura, (sockaddr *)&Server, sizeof(Server))) == -1){
printf("Problém s pojmenovanim socketu. Konec. \n");
return 16;
}

if(listen(roura,10) == -1){
printf("Problém s otevrenim fronty . Konec. \n");
return 32;
}

pthread_attr_init(&nastavenivlakna);

do{

addrlen = sizeof(Klient[0]);


klient[cislo_klienta] = accept(roura,(sockaddr *)&Klient[cislo_klienta],&addrlen);
// navazani spojeni
if(klient[cislo_klienta] <= 0){
printf("Chyba spojení.");
close(roura);
return (NULL);
}else{

pxp.cislo = pocet_vlaken;
pthread_create(&vlakna[pocet_vlaken++],&nastavenivlakna,obsluha_klienta,(void *)&pxp);

}}
while(++count <= 1024);
printf("Server byl ukončen.\n");

close(roura);
return 0;
}
[/code]

Program využívá knihovny lpthread pro vícevláknové zpracování více spojení z pomocí jednoho socketu - bohužel se mi nedaří více spojení najednou realizovat - po připojení druhého klienta spadnou obě spojení. Jako klienty používám [i]netcat[/i], ten ukončuji pomocí Ctrl+c. Proto se vlákno ukončí po přijetí 0 bytů dat. Nevíte v čem by mohla být chyba? Je to tím, že je potřeba mít pro každé spojení extra socket (tedy dělám naprostou kravinu)? Měl bych tedy program přepracovat tak aby otevřel mimo jednoho socketu X socketů (třeba v samostatných vláknech?)? A nebo je to jenom nějaká triviální chyba? Děkuji předem za reakce

Citovat příspěvek

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: