Ok,
first how to run my program:
#include <stdio.h> //printf #include <string.h> //memset #include <stdlib.h> //exit(0); #include <arpa/inet.h> #include <sys/socket.h> #include <sys/types.h> #include <time.h> #include <netinet/tcp.h> #include <getopt.h> #include <string.h> #include <fcntl.h> #include <openssl/md5.h> #include <limits.h> #define BUFLEN 100 //Max length of buffer void die(char *s) { perror(s); exit(1); } struct Wiadomosc{ int nr_ksiegi; int jednostka; int czas; int port; }; char *str2md5(const char *str, int length) { int n; MD5_CTX c; unsigned char digest[16]; char *out = (char*)malloc(33); MD5_Init(&c); while (length > 0) { if (length > 512) { MD5_Update(&c, str, 512); } else { MD5_Update(&c, str, length); } length -= 512; str += 512; } MD5_Final(digest, &c); for (n = 0; n < 16; ++n) { snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]); } return out; } void wyslij_udp(int port, const char* adres_server, struct Wiadomosc moja); int polacz_tcp(int port, const char* server_adres); int pobierz_argument(char *optarg) { char *endptr; int val; val = (int)strtol(optarg,&endptr,0); if(endptr == optarg) { fprintf(stderr,"Niepoprawny paramtr funkcji n"); exit(EXIT_FAILURE); } return val; } void print_usage() { printf("Usage: n./client -i numer_ip -o numer_portu -k numer_ksiegi -j jednostka n-c czas -p port -d plik_wynikowy nnnumer_ip - numer ip serveran-o - numer portu serwerannumer_ksiegi - numer ksiegi Pana Tadeusza <1,12> njednostka - rodzaj wysylanych komunikatow: na) 1 - wysylanie sa cale linie nb) 2 - wysylanie sa slowa i nowe linie nc) 3 - wysylanie sa znaki(litery,sredniki...) nczas - czas pomiedzy poszczegolnymi komunikatami nport - port otrzymywanych komunikatow n"); } int main(int argc, char *argv[]) { int option = 0; int ksiega = -1, jednostka = -1, czas = -1, port =-1,port2=-1; int sockfd = 0, n = 0; char *line; size_t len = 0; char recvBuff[LINE_MAX]; char* adres; struct Wiadomosc moja; int fd; char* plik_wynikowy; if(argc ==1) { print_usage(); exit(EXIT_FAILURE); } while ((option = getopt(argc, argv,"k:j:c:p:i:o:d:")) != -1) { switch (option) { case 'i' : if(strlen(optarg) < 7 || strlen(optarg) > 21) { fprintf(stderr,"niepoprawny adres ip n"); exit(EXIT_FAILURE); } adres = optarg; break; case 'o' : port2 = pobierz_argument(optarg); if( port2 < 0 || port2 > 65535 ) { fprintf(stderr,"niepoprawna wartosc ksiegi! n"); exit(EXIT_FAILURE); } break; case 'k' : ksiega = pobierz_argument(optarg); if( ksiega < 0 || ksiega > 12 ) { fprintf(stderr,"niepoprawna wartosc ksiegi! n"); exit(EXIT_FAILURE); } break; case 'j' : jednostka = pobierz_argument(optarg); if(jednostka < 1 || jednostka > 3) { fprintf(stderr,"niepoprawna wartosc jednostki! n"); exit(EXIT_FAILURE); } break; case 'c' : czas = pobierz_argument(optarg); if(czas < 0 || czas > 2000) { fprintf(stderr,"niepoprawna wartosc czasu! n"); exit(EXIT_FAILURE); } break; case 'p' : port = pobierz_argument(optarg); if(port < 0 || port > 65535) { fprintf(stderr,"niepoprawna wartosc portu! n"); exit(EXIT_FAILURE); } break; case 'd' : if(strlen(optarg) < 2 ) { fprintf(stderr,"niepoprawny plik wynikowy n"); exit(EXIT_FAILURE); } plik_wynikowy = optarg; break; default: print_usage(); exit(EXIT_FAILURE); } } moja.nr_ksiegi = ksiega; moja.jednostka = jednostka; moja.czas = czas; moja.port = port; wyslij_udp(port2,adres,moja); // now WAITING FOR CONNECTION - ENJOY ! sleep(1); fd = open(plik_wynikowy, O_WRONLY | O_CREAT | O_TRUNC); memset(recvBuff,0,sizeof(recvBuff)); sockfd = polacz_tcp(5000, adres); fprintf(stdout,"Trwa transmisja...n"); while( ( recv(sockfd,recvBuff,sizeof(recvBuff),0) ) > 0 ) { char *wiad; //recvBuff[n] = 0; write(fd,recvBuff,strlen(recvBuff)); /* if(fprintf(stdout,"%s",recvBuff) == EOF) { perror("fprintf"); } fflush(stdout); */ // odebral - teraz wyslac wiad = str2md5(recvBuff,strlen(recvBuff)); if( send(sockfd,wiad,33,0) == -1 ) { fprintf(stderr, "Failure Sending Messagen"); } free(wiad); bzero( recvBuff, sizeof( recvBuff ) ); } if(n<0) { printf("read error"); } close(fd); return 0; } void wyslij_udp(int port, const char* adres_server, struct Wiadomosc moja) { struct sockaddr_in si_other; int s, i ; int slen = sizeof(si_other); if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { die("socket"); } memset((char *) &si_other, 0, sizeof(si_other)); si_other.sin_family = AF_INET; si_other.sin_port = htons(port); if (inet_aton(adres_server , &si_other.sin_addr) == 0) { fprintf(stderr, "inet_aton() failedn"); exit(1); } //send the message if (sendto(s, (struct Wiadomosc*)&moja, 1024 + sizeof(moja) , 0 , (struct sockaddr *) &si_other,slen)==-1) { die("sendto()"); } close(s); } int polacz_tcp(int port, const char* server_adres) { int sockfd = 0,r; struct sockaddr_in serv_tcp; if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) { die("socket"); } memset(&serv_tcp,0,sizeof(serv_tcp)); serv_tcp.sin_family = AF_INET; serv_tcp.sin_port = htons(port); if(inet_pton(AF_INET,server_adres,&serv_tcp.sin_addr) < 0) { die("inet pton"); } if(connect(sockfd,(struct sockaddr *)&serv_tcp, sizeof(serv_tcp))< 0) { die("conect"); } return sockfd; }
my server
#include <stdio.h> //printf #include <string.h> //memset #include <stdlib.h> //exit(0); #include <arpa/inet.h> #include <sys/socket.h> #include <time.h> #include <netinet/tcp.h> #include <getopt.h> #include <dirent.h> #include <openssl/md5.h> #define SERVER "127.0.0.1" struct Wiadomosc { int nr_ksiegi; int jednostka; int czas; int port; }; void die(char *s); char* getWord(FILE *fp); void print_usage(); int pobierz_argument(char *optarg); struct Wiadomosc* wczytaj_udp(int port); int lacz_tcp(int port); char* stradd(const char* a, const char* b); char* str2md5(const char *str, int length); int odbierz_i_policz_md5(int gniazdo,char *str1, int length) { char *out = (char*)malloc(33); char *wiad; if(recv(gniazdo, out, 33,0) != -1) { wiad = str2md5(str1,length) ; if (strncmp (wiad,out,33) == 0) { free(out); free(wiad); return 1; } else { free(out); free(wiad); return 0; } } else{ fprintf(stdout,"Recv error! n"); exit(EXIT_FAILURE); } } int main(int argc, char *argv[]) { int option = 0; int listenfd = 0; int connfd = 0; int sposob = 1; int port=-1; char* katalog; int j=0; char sendBuff[100]; time_t ticks; FILE *stream; char *ksiegi[12] = {"/1.txt","/2.txt","/3.txt","/4.txt","/5.txt","/6.txt","/7.txt","/8.txt","/9.txt","/10.txt","/11.txt","/12.txt"}; DIR* dir; struct Wiadomosc * wiadomosc; if(argc ==1) { print_usage(); exit(EXIT_FAILURE); } while ((option = getopt(argc, argv,"p:k:")) != -1) { switch (option) { case 'p' : port = pobierz_argument(optarg); if( port < 0 || port > 65535 ) { fprintf(stderr,"niepoprawna wartosc ksiegi! n"); exit(EXIT_FAILURE); } break; case 'k' : if( (strlen(optarg) < 3) || ((dir = opendir(optarg)) == NULL) ) { fprintf(stderr,"niepoprawny katalog n"); exit(EXIT_FAILURE); } katalog = optarg; break; default: print_usage(); exit(EXIT_FAILURE); } } //ksiegi for(j=0;j<12;j++) { ksiegi[j] = stradd(katalog,ksiegi[j]); } wiadomosc = wczytaj_udp(port); printf("Nr ksiegi: %d nJednostka: %d nCzas: %d nPort: %d n" , wiadomosc->nr_ksiegi,wiadomosc->jednostka, wiadomosc->czas, wiadomosc->port); sposob = wiadomosc->jednostka; stream = fopen(ksiegi[(wiadomosc->nr_ksiegi)-1],"r"); if(stream == NULL) die("open fail "); memset(sendBuff,0,sizeof(sendBuff)); listenfd = lacz_tcp(wiadomosc->port); listen(listenfd,10); //max number of connections printf("waiting for connections..n"); while(1) { ssize_t read; size_t len = 0; char* line = NULL; char* word; int j; char znak[0]; int czas = wiadomosc->czas; connfd = accept(listenfd,(struct sockaddr*) NULL,NULL); if(sposob == 1) { while( (read = getline(&line,&len,stream) ) != -1) { write(connfd,line,read); // raad = zwraca wartosc ile //czyta po linii, to jest ok sleep(czas); // mala precyzja if( !odbierz_i_policz_md5(connfd,line,read) ) { perror("Blad MD5 n"); } } } else if(sposob == 2) { while(word = getWord(stream)) { //printf("%s",word); send(connfd,word,strlen(word),MSG_CONFIRM); sleep(czas); if( !odbierz_i_policz_md5(connfd,word,strlen(word)) ) { perror("Blad MD5 n"); } } } else if(sposob == 3) { while( (word = fgets(znak,2,stream)) != NULL) { send(connfd,word,strlen(word),MSG_CONFIRM); sleep(czas); if( !odbierz_i_policz_md5(connfd,word,strlen(word)) ) { perror("Blad MD5 n"); } } } close(connfd); sleep(1); free(line); } fclose(stream); free(wiadomosc); return 0; } char* stradd(const char* a, const char* b){ size_t len = strlen(a) + strlen(b); char *ret = (char*)malloc(len * sizeof(char) + 1); *ret = ''; return strcat(strcat(ret, a) ,b); } char *getWord(FILE *fp) { int n = 0; char word[100]; int ch; // get line and get word while(ch = fgetc(fp)) { if(ch == EOF) return NULL; else if(isalpha(ch)) word[n++] = ch; else if(ch == 'n') { word[n++] = 'n'; break; } else if(isspace(ch)) { word[n++] = ' '; break; } else break; } word[n] = ''; return strdup(word); } void die(char *s) { perror(s); exit(1); } void print_usage() { printf("Usage: n./server -p numm -kn p- numer portunk-katalogn"); } int pobierz_argument(char *optarg) { char *endptr; int val; val = (int)strtol(optarg,&endptr,0); if(endptr == optarg) { fprintf(stderr,"Niepoprawny paramtr funkcji n"); exit(EXIT_FAILURE); } return val; } struct Wiadomosc* wczytaj_udp(int port) { struct sockaddr_in si_me, si_other; struct Wiadomosc * temp = malloc(sizeof(struct Wiadomosc)); int s, i, slen = sizeof(si_other) , recv_len; int r; //create a UDP socket if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { die("socket"); } // zero out the structure memset((char *) &si_me, 0, sizeof(si_me)); si_me.sin_family = AF_INET; si_me.sin_port = htons(port); si_me.sin_addr.s_addr = htonl(INADDR_ANY); //bind socket to port if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1) { die("bind"); } //keep listening for data printf("Waiting for data..."); fflush(stdout); //try to receive some data, this is a blocking call if ((recv_len = recvfrom(s, temp,sizeof(* temp), 0, (struct sockaddr *) &si_other, &slen)) == -1) { die("recvfrom()"); } close(s); return temp; } int lacz_tcp(int port) { int listenfd = 0; struct sockaddr_in serv_tcp, saddr; int r; listenfd = socket(AF_INET,SOCK_STREAM,0); // now TCP memset(&serv_tcp,0,sizeof(serv_tcp)); serv_tcp.sin_family = AF_INET; serv_tcp.sin_addr.s_addr = htonl(INADDR_ANY); serv_tcp.sin_port = htons(port); if(bind(listenfd,(struct sockaddr*)&serv_tcp,sizeof(serv_tcp)) < 0) { die("bind()"); } return listenfd; } char *str2md5(const char *str, int length) { int n; MD5_CTX c; unsigned char digest[16]; char *out = (char*)malloc(33); MD5_Init(&c); while (length > 0) { if (length > 512) { MD5_Update(&c, str, 512); } else { MD5_Update(&c, str, length); } length -= 512; str += 512; } MD5_Final(digest, &c); for (n = 0; n < 16; ++n) { snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]); } return out; }
How to compile?
server: gcc server.c -o server -lcrypto
client: gcc client.c -o client -lcrypto
You have to create dirr like mydir and put file 1.txt.
How to run?
./server -p 12345 -k ksiegi/
./client -i 127.0.0.1 -o 12345 -k 1 -j2 -c 1 -p 5432 -d XX
What is wrong with my code?
First I try to connect with UDP
and send data – works great. But after that – I want to use data and create TCP
connection and NOW:
Sometimes it is work, sometimes fails. Why? When I am putting port like 5000 -> works, when I am trying 5432 or 5000 my output : Connectron refused.
Any idea? .
Advertisement
Answer
listenfd = lacz_tcp(wiadomosc->port);
From what I can tell, the port has not been initialized before you call bind. Log the port to be sure that the server is listening on the correct port.