/* netwerk interface */ /* voorlopig alleen voor mingw32 maakt gebruik van wsock32 */ #include #include #include #include #ifdef __MINGW32__ #include #else #include #include #include #ifdef __DJGPP__ #include #else #define lsck_perror perror #endif #endif #ifndef MAXPATH /* schijnt niet overal te zijn gedefinieerd */ #define MAXPATH 1024 #endif #include /* time() geeft een event per seconde */ /* _sleep() geeft een event per 0.001 sec (alleen mingw32?)*/ /* dit is een equivalent voor sleep(i) */ /*void wait(int i){ time_t wait; wait = time(0); while(wait+i>=time(0)); } */ /* netwerk init */ #ifdef __MINGW32__ /* init winsock */ static int init_WsockDll(void){ int err; WORD wVersionRequested; /* Consist Version Nr. of Wsock32.dll */ WSADATA wsaData; /* Info about Sockets */ wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) return (err); if (LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion )!=1) { WSACleanup( ); return(-1); } return(0); } int netwerk_init(){ /* only by winsock */ if (init_WsockDll()!=0) { perror("Socket Init Failed "); return -1; } else return 0; } void netwerk_end(){ WSACleanup( ); } void netwerk_close(int socket){ closesocket(socket); } #else int netwerk_init(){ return 0;} void netwerk_end(){ } void netwerk_close(int socket){ #ifdef __DJGPP__ sleep(5); #endif close(socket); } /* DJCPP : close() wordt gedaan met RST , hetgeen de onderweg zijnde data vernield . Met Linger moet dat tevoorkomen zijn maar dat is niet geimplementeerd . Hopelijk is een sleep() van 5 sec genoeg.*/ #endif /* netwerk_open("127.0.0.1:5000",mode) -> antwoord met -1 error of een socket_id mode = c = client, s = server, a = accept */ int netwerk_open(char* adres,char* mode) { int sd; struct sockaddr_in sad; int sad_length=sizeof(sad); int cl; struct sockaddr_in clt; int cl_length =sizeof(clt); /*client adres*/ char hostname[MAXPATH]="127.0.0.1"; /* local host */ struct hostent *hip; int port,reuse_addr=1; struct linger ln; int ln_size; #ifndef __DJGPP__ if (mode[0] == 'a') { /* accept */ // NO-Blocking geeft hoge cpu tijd , dit om cpu tijd naar beneden tebrengen // nu via select met een time-out van 1 sec . // blocking mag niet omdat anders de time-out pagina niet werkt . int sock_select; fd_set socket_read; fd_set socket_write; struct timeval timeout; timeout.tv_sec=1; timeout.tv_usec=0; /* set fd set */ FD_ZERO(&socket_read); // FD_ZERO(&socket_write); FD_SET((int)adres,&socket_read); // FD_SET((int)adres,&socket_write); sock_select = select((int)adres+1,&socket_read,(fd_set *)0,(fd_set *)0,&timeout); if (sock_select<0){ perror("Select Failed") ;return -3; } else if (sock_select == 0 ) { return 0;/* in blocking should this happens */ } else if (FD_ISSET((int)adres,&socket_read)){ cl=accept((int)adres,(struct sockaddr *)&clt,&cl_length); if (cl>=0) { // Client Has Connected communicate using a clisd socket printf("Remote Port: %d\n",(int)ntohs(clt.sin_port) ); printf("Remote IP : %s\n", inet_ntoa(clt.sin_addr) ); /* linger heeft iets te maken met het opvangen van onvolledige packets , werkt alleen in linux en unix maar wat het doet is mij onduidelijk */ ln.l_onoff = 1; ln.l_linger= 0xFFFF; ln_size = sizeof(ln); //#ifdef __MINGW32__ /* mingwin has 4th parameter as pointer of type char */ setsockopt(cl,SOL_SOCKET,SO_LINGER,(char*)(&ln),ln_size); /* op het oog gezien trek Linux zich er niets van aan !? */ //#else // setsockopt(cl,SOL_SOCKET,SO_LINGER,&ln,ln_size); //#endif memset(&ln,0,sizeof(ln)); getsockopt(cl,SOL_SOCKET,SO_LINGER,(char*)(&ln),&ln_size); printf("onoff %i, linger %i, len %i\n",ln.l_onoff,ln.l_linger,ln_size); } return cl; } return -1;/* error */ } /* sloop adres in hostname,port */ cl=(int)(strchr(adres,':')-adres); if (cl<= 0) { perror("Incorrect adres "); return -1; } strncpy(hostname,adres,cl); port=atoi(adres+cl+1); printf("host %s : %d\n",hostname,port); /* maak nieuw socket */ if((sd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==-1) { printf("Socket object Failed Creation "); return -1; } /* re_use addr betekend in linux ,wacht niet op TIMEOUT voordat socket wordt vrij gegeven . betekend in winsock , geen iedee */ setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,(char*)(&reuse_addr),sizeof(reuse_addr)); /* adres in sad=socket adres */ memset(&sad,0,sad_length); /* clear server adress structure */ sad.sin_family = AF_INET; sad.sin_port = htons(port); if (mode[0] == 'c') { /* client */ if((hip=gethostbyname(hostname))==NULL) { printf("getHostbyname Failed for : %s\n",hostname); return -1; } memcpy(&sad.sin_addr,hip->h_addr,hip->h_length); //sad.sin_addr.s_addr = inet_addr(hostname); /* inet_addr server */ //printf("Try to Connected to Server IP %s\n",inet_ntoa(sad.sin_addr)); if(connect(sd,(struct sockaddr *)&sad,sizeof(sad))==-1) { printf("Connection Failed "); return -1; } printf("Connected to Server IP %s\n",inet_ntoa(sad.sin_addr)); return sd; } else if (mode[0] == 's') { /* server */ sad.sin_addr.s_addr = htonl(INADDR_ANY);/* server listen to any*/ if(bind(sd,(struct sockaddr *)&sad,sad_length )==-1) { printf("Unable to bind port address "); return -1; } listen(sd,10); // Queue at most 10 connections // set to NO Blocking // fcntl(sd,F_SETFL,O_NONBLOCK); werkt niet in mingw32 // long iMode=1; // ioctlsocket(sd,FIONBIO,&iMode); // dit vreet cpu tijd in de accept() function geeft 100% cpu use . printf("Server started\n"); printf("Server IP %s\n",inet_ntoa(sad.sin_addr)); printf("Server Port: %d\n",(int)ntohs(sad.sin_port) ); return sd; } else { /* error in mode optie */ printf ("illigaal mode optie\n"); return -1; } #endif return -1; } int netwerk_write(int socket,char buf[],int size){ /* return -1 error */ int i,ret; #ifndef __DJGPP__ for(i=0;i=time(0)); /* this are seconds */ return 0;/* time out */ } /* interface for G77 */ short int netwerk_init__(){ return (short int)netwerk_init();} int netwerk_open__(int* name,char* mode){ /* dit is & blijft goor . name is een pointer naar een integer of naar een string fortran sluit string niet af . het gaat goed omdat de string eindigd op een nummer n.l. het poort nummer (dus eindigen op een naam mag niet !!!!) */ /* de name lokaal naar naam te zetten en dan de laatste-1 op 0 geeft een memory error */ if(mode[0]=='a') { return netwerk_open((char*)(*name),mode);/* gives a type conflict */ }else{ return netwerk_open((char*)name,mode); } } /* in g77 calls with char the length are as exstra parameters */ short int netwerk_puts__(int *sock,char *buf,int size){ return (short int)netwerk_write(*sock,buf,size);} short int netwerk_write__(int *sock,char *buf,int *size){ return (short int)netwerk_write(*sock,buf,*size);} short int netwerk_read__(int *sock,char *buf,int *size,int *timeout){ return (short int)netwerk_read(*sock,buf,*size,*timeout);} void netwerk_close__(int *sock){ netwerk_close((int)*sock);} void netwerk_end__(){ netwerk_end(); }