sockety

Sekcia: Programovanie 21.12.2007 | 17:55
Matus Valo   Návštevník
Dobry den. Som studentom TU v KE a mam mensi problem so socketmi. Mali sme naprogramovat kaskadu procesov, ktore si odovzdavaju retazce. Mam len jeden problem pri sockete, pretoze viem, ze proces dostane vsetky slova (cez zdielanu pamat) a hned to zapise do socketu (socket je typu SOCK_STREAM) ale socketovy server nedostane vsetky. (socketovy server sme dostali uz ako binarku). Ked vlozim medzi to sleep(1) tak mi vsetko bezi dobre. Nuz moze sa stat, zeby client prepisal data co zapisal predtym?? (je socket bufferovany ako pipe?) a co som sa pytal spoluziakov tak hovoria, ze im sleep netrebalo a ide to aj bez toho... Tak neviem. Tu je zdrojovy kod:
/*
Cita zo zdielanej pamate SM2 a posiela na proces SERV1.
parametre: kluc semaforu S2, kluc zdielanej pamate SM2, cislo portu Serv1 
*/
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include<sys/socket.h>
#include<netinet/in.h>										/*kvoli struct sockaddr_in*/
#include<arpa/inet.h>
#include<signal.h>
#include<string.h>
#define DEBUG
#include "zadanie.h"

static int sem_p(int sem_id){								/* *CERVENA* na citacom semafore*/
	struct sembuf sem[2];									/* zapisovaci nemenim (je na nom *CERVENA* )*/
	sem[SEM_WR].sem_num=SEM_WR;
	sem[SEM_WR].sem_op=0;									/*zapis. sem. nemenim*/
	sem[SEM_WR].sem_flg=SEM_UNDO;
	sem[SEM_RD].sem_num=SEM_RD;
	sem[SEM_RD].sem_op=-1;									/*citaci je *CERVENA* */
	sem[SEM_RD].sem_flg=SEM_UNDO;
	return semop(sem_id,sem,2);
}
static int sem_v(int sem_id){								/* *ZELENA* na zapisovacom semafore*/
	struct sembuf sem[2];									/*citaci nemenim,(je na nom *CERVENA*)*/
	sem[SEM_WR].sem_num=SEM_WR;
	sem[SEM_WR].sem_op=1;									/* *ZELENA* na zapis. sem.*/
	sem[SEM_WR].sem_flg=SEM_UNDO;
	sem[SEM_RD].sem_num=SEM_RD;
	sem[SEM_RD].sem_op=0;									/* citaci nemenim(je na nom *CERVENA*)*/
	sem[SEM_RD].sem_flg=SEM_UNDO;
	return semop(sem_id,sem,2);
}

int main(int argc, char *argv[]){
	char string[MAX_LEN];
	union semun semdel;
	struct shmid_ds shm_rm;								/*kvoli zmazaniu zdiel. pamate*/
	int sm2_id, s2_id;									/*id zdiel. pamate SM2 a semaforu s2*/
	void *temp;												/*docasny ukazovatel na zdiel. pamat*/
	char *sm2;												/*string ulozeny v zdiel. pamati*/
	int sockfd;												/*file descriptor socketu*/
	struct sockaddr_in servaddr;						/*adresa serveru*/
	
	#ifdef DEBUG
		fprintf(stderr, "DEBUG:d args:%s, %s, %s\n", argv[1], argv[2], argv[3]);
	#endif

	/*vytvorenie zdielanej pamate*/
	if((sm2_id=shmget((key_t) atoi(argv[2]), (size_t) MAX_LEN*sizeof(char), 0600))==-1) ERR_EXIT("SM2")
	temp=shmat(sm2_id, NULL, SHM_RDONLY);						/*pripojenie zdiel. pamate*/
	if((int) temp==-1){ ERR_EXIT("SM2"); }						/*chyba*/
	sm2=(char *) temp;												/*priradzujem ukazovatel na char zdiel. pamati*/
	#ifdef DEBUG
		printf("DEBUG:d:Shared memory attached at:0x%X\n",(unsigned int) temp);
	#endif

	/*vytvorenie semaforov*/
	if((s2_id=semget((key_t) atoi(argv[1]), 2, 0600|IPC_CREAT))==-1) ERR_EXIT("S2");	/*vytvorenie semaforu*/
	#ifdef DEBUG
		D_PRINT("process d ready");
	#endif
	/*vytvorenie socketu*/
	if((sockfd=socket(PF_INET, SOCK_STREAM, 0))==-1) ERR_EXIT("d:Cannot creat socket");
	servaddr.sin_family = AF_INET;								/*domena AF_INET - tj. protokol TCP/IP*/
	servaddr.sin_port = htons(atoi(argv[3]));					/*cislo portu servera*/
	servaddr.sin_addr.s_addr=inet_addr(LOCALHOST_ADDR);	/*adresa servera*/
	printf("%s\n", argv[3]);
	if(connect(sockfd, (struct sockaddr *) &servaddr, (socklen_t) sizeof(servaddr))==-1)
		ERR_EXIT("d:Error when connecting to socket server"); /*pripojenie sa ku socketu serv1*/
	if(kill(getppid(),SIGUSR1)==-1) ERR_EXIT("proc d:killing parent")								/*proces d je pripraveny*/
	#ifdef DEBUG
		D_PRINT("process d ready");
	#endif
	while(1){
		if(sem_p(s2_id)==-1) ERR_EXIT("d:sem S2:sem_p")								/* *CERVENA* */
		#ifdef DEBUG
			D_PRINT("d is entering critical area");
		#endif
		strcpy(string, sm2);
		if(write(sockfd, string, strlen(string)+1)==-1) ERR_EXIT("d:write:")
		#ifdef DEBUG
			D_PRINT("d is exiting critical area");
		#endif
		if(sem_v(s2_id)==-1) ERR_EXIT("d:sem S2_sem_v");								/* *ZELENA* */
		#ifdef DEBUG
			fprintf(stderr, "DEBUG: d:in socket written:");
			write(2, string, strlen(string));
			printf("\n");
		#endif
	}
}
D_PRINT a ERR_EXIT su makra:
#ifdef DEBUG
	#define D_PRINT(string) fprintf(stderr,"DEBUG: %s\n",string)
#endif
#ifndef ERR_EXIT
	#define ERR_EXIT(strerr) {perror(strerr); exit(1);}
#endif
    • Re: sockety 21.12.2007 | 18:20
      Avatar gUbA Ubuntu, Debian  Používateľ
      Tiez som studentom TU-KE, a viem, ze tu pomoc hladas marne ;) . Teda co sa tyka otazok takehoto typu. Vela zdaru!!!
      sudo apt-get remove windows
      • Re: sockety 21.12.2007 | 21:38
        Matus Valo   Návštevník
        Heh diky. sak za pokus to stoji