Problem with socket C

Asked

Viewed 123 times

1

Good afternoon to you all! I am doing academic work on Sockets in C Language, in which I need to create an MP3 file transfer program in Windows. In it I have two programs, client and tracker, in which they must follow the operation:

  1. Client queries certain file on tracker; [DONE]
  2. Tracker checks the database for the file; [DONE - database data file. txt same]
  3. Tracker sends a response to the client whether the file exists or not (if it exists, send the client’s IP address to that file); [PROBLEM]
  4. Customer requests sending the file to customer holder;
  5. (...)

The program extends to other functions, but the problem is in topic 3. I don’t have much knowledge of this library and I’ve researched several places on the subject, but I come to algorithms that I can’t fit into mine through reverse engineering. The customer communication with the tracker was performed successfully, but I could not do the reverse, could anyone help me with this? I tried to put a path() in the tracker and recvfrom() in the client, but I did not succeed. Thanks for your attention!

TRACKER CODE:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib") 
#define BUFLEN 512  
#define PORT 8888  

int servidorON(){
    SOCKET s;
    struct sockaddr_in server, si_other;
    int slen , recv_len;
    char buf[BUFLEN];
    char message[BUFLEN];
    WSADATA wsa;
    char *alvo;

    slen = sizeof(si_other) ;

    //Inicializar Winsock
    printf("\nInicializando Winsock...");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("Erro de Winsock");
        exit(EXIT_FAILURE);
    }
    printf("\n\tInicializado.\n");

    //Criando socket
    if((s = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
    {
        printf("Socket nao pode ser criado\n");
    }
    printf("\tSocket criado.\n");

    //Preparando estrutura sockaddr_in
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( PORT );

    //Bind
    if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
    {
        printf("Erro de bind()");
        exit(EXIT_FAILURE);
    }
    puts("\tBind realizado.");
    printf("Aguardando transacoes...\n");

    //Repetição que aguarda as transações
    while(1)
    {

        fflush(stdout);

        //Limpa o buffer para o recebimento de dados
        memset(buf,'\0', BUFLEN);

        //Tenta receber dados com blocking call
        if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR)
        {
            printf("Erro de recvfrom()!\n");
            exit(EXIT_FAILURE);
        }

        //Exibe os dados recebidos
        printf("\nPacote recebido de %s:%d", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
        printf("\nRequisicao: %s\n" , buf);


        alvo=verificarBancoDados(buf);
        if(alvo == 0){
            printf("Arquivo nao encontrado.\n");
        }else{
            //aqui é pra ser colocado o envio ao cliente requisitante do ip do detentor do arquivo ao invés desse print(deve ser apagado)
            printf("Encontrado em: %s\n", alvo);
            //sendto(s, alvo, strlen(alvo) , 0 , (struct sockaddr *) &si_other, sizeof(si_other));
        }

        //Passos:
        //verificar se existe no bd [FEITO]
        //retornar ao usuário se tem ou não
        //se existir responder ao usuário quem tem aquele arquivo
    }

    closesocket(s);
    WSACleanup();

    return 0;

}

int verificarBancoDados(char *requisicaoBuf){
    char ip[16], chave[32];
    int i;
    FILE *arq = fopen("bancoDeDados.txt", "rt");

    while( (fscanf(arq, "%s %s\n", &ip, &chave)) != EOF){
        if((strcmp(chave, requisicaoBuf))== 0){
            printf("O arquivo '%s' foi encontrado no cliente %s\n", &chave, &ip);
            fclose(arq);
            return ip;
        }
    }
    fclose(arq);
    return 0;
}


// MAIN

int main(){
    servidorON();
    return 0;
}

CLIENT CODE:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib") 
#define SERVER "127.0.0.1"  
#define BUFLEN 512  
#define PORT 8888   

int requisitarArq(){
    struct sockaddr_in server, si_other;
    int s, slen=sizeof(si_other);
    char buf[BUFLEN];
    char message[BUFLEN];
    WSADATA wsa;

    //Inicializar Winsock
    printf("\nInicializando Winsock...\n");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("Erro ao inicializar Winsock!");
        exit(EXIT_FAILURE);
    }
    printf("Inicializado.\n");

    //Criar Socket
    if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
    {
        printf("Erro de socket()!");
        exit(EXIT_FAILURE);
    }

    //Configuração da estrutura de endereço
    memset((char *) &si_other, 0, sizeof(si_other));
    si_other.sin_family = AF_INET;
    si_other.sin_port = htons(PORT);
    si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);

    //Comunicação
    printf("Requisitar arquivo: ");
    scanf("%s", &message);

    //Envio da mensagem
    if (sendto(s, message, strlen(message) , 0 , (struct sockaddr *) &si_other, slen) == SOCKET_ERROR){
        printf("Erro de sentTo()!");
        exit(EXIT_FAILURE);
    }
    //esse print abaixo deve aparecer somente se o arquivo for encontrado no bd do rastreador,
    //se ele nao for encontrado, é pra printar só que não foi
    //printf("\nServidor: arquivo '%s' encontrado no cliente %s", message, buf);

    //o ip enviado deverá gerar uma nova requisição ao novo cliente para o envio do arquivo.
    /*memset(buf,'\0', BUFLEN);
    recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &server, sizeof(server));
    printf("\nServidor: arquivo '%s' encontrado no cliente %s", message, buf);  */

    closesocket(s);
    WSACleanup();

    return 0;
}
// MAIN

int main(){
    requisitarArq();
    return 0;
}

1 answer

0


As I had commented on the Stack Overflow in English, you have to put a Listener in the client, also, using another thread,

#include <pthread.h>
...
// protótipos
int requisitaArq();
int clienteON();

void* clienteONThread(void* vargp)
{
    clienteON();
}

void* requisitaArqThread(void* vargp)
{
    requisitaArq();
}

int main(int argc, char* argv[])
{
    pthread_t on;
    pthread_t arq;
    pthread_create(&on, NULL, clienteONThread, NULL);
    pthread_create(&arq, NULL, requisitaArqThread, NULL);
    pthread_join(on, NULL);
    pthread_join(arq, NULL);

    return 0;
}
...

Also, you need to create on tracker, a list of Ips of customers that connect to it - take the si_other.sin_addr, or have already hardcoded - to be able to consult customers, back.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.