2016-02-21 149 views
-5

好了TCP套接字,连接被拒绝 - 在linux

第一如何运行我的程序:

#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 \n\nnumer_ip - numer ip servera\n-o - numer portu serwera\nnumer_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 Message\n"); 
     } 
     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() failed\n"); 
     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; 
} 

我的服务器

#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 = '\0'; 
    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] = '\0'; 
    return strdup(word); 
} 

void die(char *s) 
{ 
    perror(s); 
    exit(1); 
} 

void print_usage() { 
    printf("Usage: \n./server -p numm -k\n p- numer portu\nk-katalog\n"); 

} 

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; 
} 

如何编译?

服务器:GCC server.c -o服务器-lcrypto

客户端:GCC client.c -o客户-lcrypto

你必须创建DIRR像MYDIR并把文件1。文本。

如何运行?

./server -p 12345 -k ksiegi/

./client -i 127.0.0.1 -o 12345 -k 1 -j2 -C 1 -p 5432 -d XX

我的代码有什么问题? 首先,我尝试连接UDP并发送数据 - 效果很好。但之后 - 我想要使用数据并创建TCP连接和现在:

有时它是工作,有时会失败。为什么?当我将端口设置为5000 - >工作时,当我尝试5432或5000时我的输出 :Connectron拒绝。

有什么想法? 。

+3

请构造一个[最小测试用例](http://stackoverflow.com/help/mcve)。 –

回答

0
listenfd = lacz_tcp(wiadomosc->port); 

从我所知道的,在调用bind之前,该端口还没有被初始化。记录端口以确保服务器正在侦听正确的端口。

+0

你能告诉我如何登录端口?在我调用'lacz_tcp'之前我必须这样做,不是吗? – matkuz

+0

'printf'用于记录。无论你之前还是之后都做这件事并不重要,'lacz_tcp'不会修改它的参数吧? – Joni