连接被拒绝 - linux中的tcp套接字

时间:2016-02-21 17:16:21

标签: c linux sockets tcp

好的,

首先如何运行我的程序:

#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 server -lcrypto

     

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

你必须创建像mydir这样的dirr并放置文件1.txt。

如何运行?

  

./ server -p 12345 -k ksiegi /

     

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

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

有时它是工作,有时会失败。为什么?当我把端口像5000 - &gt;我正在尝试5432或5000 我的输出 :Connectron拒绝了。

有什么想法吗? 。

1 个答案:

答案 0 :(得分:0)

listenfd = lacz_tcp(wiadomosc->port);

据我所知,在调用bind之前,端口尚未初始化。记录端口以确保服务器正在侦听正确的端口。