Shared memory v serveru – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Shared memory v serveru – C / C++ – Fórum – Programujte.comShared memory v serveru – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
Redby0
Návštěvník
26. 11. 2011   #1
-
0
-

Tak jsem tu zase. Pracuji na chatovacím serveru. Moje Idea je taková, že loginy budu uchovávat ve spojovém seznamu. Vzhledem k tomu že server je více procesní, tak jsem zvolil využít shared memory. No a samozřejmě jsem narazil na nefunčnost. Nehledě na to že se to při uložením loginu do seznamu kousne, tak navíc když se přihlasí další klient tak opět je v seznamu jen jeho login.. Není mi jasný co je na tom špatně. Případně se zamýšlím i na jiné možnosti jak ukládat loginy, ale zatím mě nic nenapadlo. Spojový seznam jsem zvolil z důvodu že mohu při odhlášení lehce odebrat login.. Děkuji moc za pomoc

#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "LList.h"

void error(char *);
void success(char *);
void send_error(int err);
void recv_error(int err);

int main(int argc, char **argv) {

	char buffer[1024];
	struct list *USERS = NULL;
	pid_t process;

	int shmid = shmget(1000, 16384, IPC_CREAT | 0666);
	USERS = shmat(shmid, NULL, 0);

	struct sockaddr_in serv_adr;
	struct sockaddr_in cli_adr;
	int listenfd, sd_current, clilen, stat;

	if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		error("Unable to create socket.\n");
	} else {
		printf("Socket created.\n");
	}

	serv_adr.sin_family = AF_INET;
	serv_adr.sin_addr.s_addr = INADDR_ANY;
	serv_adr.sin_port = htons(1024);

	if (bind(listenfd, (struct sockaddr*) &serv_adr, sizeof(serv_adr)) < 0) {
		error("Unable to bind adress.\n");
		close(listenfd);
		exit(1);
	} else {
		printf("Client adress obtained.\n");
	}

	listen(listenfd, 5);

	while (1) {
		clilen = sizeof(cli_adr);
		sd_current = accept(listenfd, (struct sockaddr*) &cli_adr, &clilen);
		if (sd_current < 0) {
			error("Unable to accept connection.\n");
		} else {
			printf("Connection established.\n");
		}
		process = fork();
		if (process == 0) {
			close(listenfd);
			shmid = shmget(1000, 16384, IPC_CREAT | 0666);
			USERS = shmat(shmid, NULL, 0);
			while (1) {
				stat = recv(sd_current, buffer, 1024, 0);
				recv_error(stat);
				int a;
				for (a = 0; a < strlen(buffer); a++) {
					if (buffer[a] == 10) {
						buffer[a] = '\0';
					}
				}
				if ((strncmp(buffer, "#LOGIN#", 7)) == 0) {
					stat = send(sd_current, "OK\n", 3, 0);
					send_error(stat);
					add(buffer, &USERS);
					print(USERS);
					break;
				} else {
					stat = send(sd_current, "ERR\n", 6, 0);
					send_error(stat);
				}
				fflush(stdout);
			}
			fflush(stdout);
			while (1) {
				stat = recv(sd_current, buffer, 255, 0);
				recv_error(stat);
				stat = send(sd_current, "OK", 5, 0);
				send_error(stat);
			}
		} else {
			close(sd_current);
		}
	}
	close(listenfd);
	return 0;
}
Nahlásit jako SPAM
IP: 78.136.138.–
KIIV
~ Moderátor
+43
God of flame
26. 11. 2011   #2
-
0
-

pripada mi trochu ujety udrzovat klienty forknutym procesem zrovna pro chat... to se hodi treba pro nejaky ftp/http server - proste kde nepotrebujes komunikovat mezi podprocesorama...

Na chat bych byt tebou zneuzil jednu jednovlaknovou aplikaci, kdy pridavas spojeni do seznamu a pouzijes nad tim select ... ten pak bud vrati, ktere file descriptory maji data na cteni, daj se zapsat(to vetsinou neni problem) nebo chybu a ty to jen zpracujes (zaroven mas vse v jednom procesu, zadny vlakna a tak podobne)

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Redby0
Návštěvník
26. 11. 2011   #3
-
0
-

#2 KIIV
No asi to bude mnohem jednoduší. Nějak jsem se snažil o ten fork(), ale už jsem začal uvažovat, že se na něj vykašlu. Takže jdu nastudovat použití toho select()

Nahlásit jako SPAM
IP: 78.136.138.–
KIIV
~ Moderátor
+43
God of flame
26. 11. 2011   #4
-
0
-
Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Redby0
Návštěvník
27. 11. 2011   #5
-
0
-

Tak jsem využil non blocking socket a mám k tomu jeden dotaz. Mámu toto nekonečnou smyčku, ale pro mě z neznámých důvodů akceptuje pouze jedno odeslaní a přijmutí. Víc toho nepřijme a netuším proč.

while (1) {

		sd_current = accept(listenfd, (struct sockaddr*) &cli_adr, &clilen);
		if (sd_current < 0) {
			//	error("Unable to accept connection.\n");
		} else {
			printf("Connection established.\n");
		}

		stat = read(sd_current, buffer, 1024);
		if (stat > 0) {
			printf("%d\n", stat);
		}
		stat = write(sd_current, "OK\n", 3);
		if (stat > 0) {
			printf("%d\n", stat);
		}
	}

Díky

Nahlásit jako SPAM
IP: 88.103.128.–
KIIV
~ Moderátor
+43
God of flame
27. 11. 2011   #6
-
0
-

chtelo by to mit kam ukladat a udrzovat ty zbyly spojeni ... takto nejspis prijmes, neco z nej nactes nebo vypises a hned v dalsim kole to uz prepise zase -1 dokud se neotevre nejake jine spojeni

(od toho se pak jeste hodi ten select a seznam socketu..)

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Redby0
Návštěvník
27. 11. 2011   #7
-
0
-

#6 KIIV
Toto je testovaci smyčka. I když tám nechám jen read() a budu vypisovat jen pokud bude vysledek > 0 tak by to přeci nemělo na -1 brát zřetel ne? Dle mě mi to nechce při druhém průchodu již nic přečíst ze socketu

Nahlásit jako SPAM
IP: 78.136.170.–
KIIV
~ Moderátor
+43
God of flame
27. 11. 2011   #8
-
0
-

tady jde o to ze kdyz nejsou data tak read vraci 0 a ukonci se okamzite co se spusti...

nicmene uplne stejne se chova i accept - bud vrati cislo socketu nebo -1 kdyz se zrovna nic nesnazi pripojit...

(veskrze to znamena ze ten cyklus pojede na maximalni rychlost (a hlavne vytizeni) protoze to nikde proste neceka)

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Redby0
Návštěvník
27. 11. 2011   #9
-
0
-

#8 KIIV
No jasně, to mi nedošlo s tím acceptem. Díky moc..

Nahlásit jako SPAM
IP: 78.136.170.–
Redby0
Návštěvník
28. 11. 2011   #10
-
0
-

#8 KIIV
Takže server zatím běží. Login i Logout funguje, akorát zatížení procesoru je na max, což se mi moc nelíbí. Ale jestli to dobře chápu, tak řešení je asi právě ten select co?

Nahlásit jako SPAM
IP: 78.136.179.–
KIIV
~ Moderátor
+43
God of flame
28. 11. 2011   #11
-
0
-

#10 Redby
jop .. muzes mu nastavit ze ma cekat na tech spojenich nekonecne dlouho nebo treba nastavit ze se ma prerusovat cekani kazdych par sekund (nebo i mikrosekund) - vytizeni je proste proto, ze se nikde neceka s furt to jede a jede

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Redby0
Návštěvník
28. 11. 2011   #12
-
0
-

#11 KIIV
OK, zkusím to implementovat. Zatím jsem použil jen usleep(), což taky pomohlo...:-) Díky moc za pomoc. Koukám ty tu jsi taky nonstop.

Nahlásit jako SPAM
IP: 78.136.179.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 39 hostů

Podobná vlákna

Shared libraries — založil Bud a Pest

MFC static shared — založil Damo

Memory leak — založil CommanderZ

Error 1: Out of Memory — založil Lukfi

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý