Shoxsz Posted April 4, 2013 at 01:19 AM Report #501514 Posted April 4, 2013 at 01:19 AM (edited) Olá pessoal, estava fazendo um programa em C usando sockets para ler um diretorio e enviar ao ciente os arquivos do diretorio, o problema é que no recebimento da mensagem sempre da erro! já peguei alguns exemplos na internet iguais ao meu e eles funcionam perfeitamente bem, mas quando volto pro meu programa, ele nunca recebe a mensagem do cliente: ... listen(sock, 10); printf("Aguardando conexao...\n"); if((sockc = accept(sock, (SOCKADDR*)&cliente, &t) == -1)) { perror("accept"); return 0; } printf("Cliente conectado!\n"); while(1) { b = recv(sockc, diretorio, MAX_DIR, 0); ... estou fazendo algo de errado no recebimento da mensagem?? Edited April 4, 2013 at 06:55 AM by pmg
HappyHippyHippo Posted April 4, 2013 at 02:14 AM Report #501515 Posted April 4, 2013 at 02:14 AM esse código é insuficiente, falta (pelo menos) o bind do socket IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Shoxsz Posted April 4, 2013 at 02:48 AM Author Report #501516 Posted April 4, 2013 at 02:48 AM cara, eu sei disso, essa é só a parte para mostrar que eu já fiz até o bind e estou utilizando 2 descritores para os sockets, um pro sevidor e o outro retornado pela função accept
HappyHippyHippo Posted April 4, 2013 at 08:58 AM Report #501536 Posted April 4, 2013 at 08:58 AM cara, eu sei disso, essa é só a parte para mostrar que eu já fiz até o bind e estou utilizando 2 descritores para os sockets, um pro sevidor e o outro retornado pela função accept pois, mas não apresentaste o código, pois não ? como sei se está bem ? como sei que o que está para trás se encontra correcto, e andas a fazer chamadas com um descritor válido ? do código que vejo, não fazes uma única sequer validação de chamada, por isso só posso assumir que o mesmo não é feito no código não apresentado IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Shoxsz Posted April 4, 2013 at 11:16 AM Author Report #501573 Posted April 4, 2013 at 11:16 AM (edited) aqui está o código: #include <stdio.h> #include <winsock.h> #include <dirent.h> #define MAX_DIR 100 #define PADRAO 4700 #define BYTES_POR_VEZ 500 #define E404 "Diretorio nao encontrado" #define DIR_OK "Diretorio encontrado" #define INICIO "inicio" WSADATA wsa; SOCKET sock, sockc; SOCKADDR_IN serv, cliente; FILE* arq;//Ultimo arquivo encontrado no diretório DIR* dir;//Diretório principal DIR* sec;//Diretório que secundário struct dirent* at; int ler_diretorio(); int ler_arquivo(char*, int); int cabecalho(const char*, int); int tamanho_arquivo(); int main() { char diretorio[MAX_DIR], buffer[bYTES_POR_VEZ]; int b; while(1) { printf("Iniciando servidor...\n"); if(WSAStartup(MAKEWORD(1, 1), &wsa) == -1) { perror("WSAStartup"); return 0; } if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); return 0; } serv.sin_family = AF_INET; serv.sin_port = htons(PADRAO); serv.sin_addr.s_addr = INADDR_ANY; int t = sizeof(serv); if(bind(sock, (SOCKADDR*)&serv, t) == -1) { perror("bind"); return 0; } listen(sock, 1); printf("Aguardando conexao...\n"); if((sockc = accept(sock, (SOCKADDR*)&cliente, &t) == -1)) { perror("accept"); return 0; } printf("Cliente conectado!\n"); while(1) { b = recv(sockc, diretorio, MAX_DIR, 0); if(b < 0) { perror("recv"); return 0; } else if(b == 0) { printf("Conexao perdida!\n"); return 0; } else { diretorio[b] = '\0'; printf("Diretorio para leitura: %s\n", diretorio); } dir = opendir(diretorio); //erro if(dir == NULL) { //Enviar mensagem de erro send(sockc, E404, strlen(E404), 0); printf("%s\n", E404); continue; } //Ler os arquivos do diretório atual while(ler_diretorio() == 1) { //Abrir o arquivo atual arq = fopen(at->d_name, "r"); if(arq == NULL) { printf("Falha ao abrir arquivo %s\n", at->d_name); continue; } //Mensagem indicando o inicio de um arquivo if(cabecalho(at->d_name, tamanho_arquivo()) == -1) { printf("Falha ao enviar arquivo %s\n", at->d_name); continue; } //ler arquivo e enviar while(ler_arquivo(buffer, BYTES_POR_VEZ) > 0) { send(sockc, buffer, strlen(buffer), 0); } fclose(arq); } } } return 0; } int ler_diretorio() { if((at = readdir(sec))) return 1; return 0; } int ler_arquivo(char* buffer, int tam) { int i; for(i = 0; i < tam; i++) { if(!feof(arq)) break; buffer[i] = fgetc(arq); } buffer[i] = '\0'; return i; } ///Enviar o cabecalho indicando inicio de arquivo para o cliente int cabecalho(const char* arquivo, int tam) { char msg[strlen(arquivo) + strlen(INICIO) + 2]; sprintf(msg, "%s %s", INICIO, arquivo); if(send(sockc, msg, strlen(msg), 0) <= 0) return -1; itoa(tam, msg, 10); //Enviar o tamanho do arquivo a ser enviado if(send(sockc, msg, strlen(msg), 0) <= 0) return -1; return 1; } int tamanho_arquivo() { fseek(arq, 0, SEEK_END); int t = ftell(arq); rewind(arq); return t; } Edited April 4, 2013 at 11:21 AM by Shoxsz
HappyHippyHippo Posted April 4, 2013 at 11:41 AM Report #501579 Posted April 4, 2013 at 11:41 AM o código parece correcto, mas para dançar o tango, são necessários 2 e o código do cliente ? IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Shoxsz Posted April 4, 2013 at 01:51 PM Author Report #501603 Posted April 4, 2013 at 01:51 PM (edited) aqui esta: #include <stdio.h> #include <winsock.h> #define MASTER "192.168.1.50" #define MAX_DIR 100 #define PADRAO 4700 #define BYTES_POR_VEZ 500 #define E404 "Diretorio nao encontrado" #define DIR_OK "Diretorio encontrado" #define INICIO "inicio" WSADATA wsa; SOCKET sock; SOCKADDR_IN info; int main() { char ip[16]; char diretorio[MAX_DIR]; char buffer[bYTES_POR_VEZ]; if(WSAStartup(MAKEWORD(2, 2), &wsa) == -1) { perror("WSAStartup"); return 0; } if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); return 0; } info.sin_family = AF_INET; info.sin_port = htons(PADRAO); printf("IP para conexao: "); fflush(stdin); scanf("%s", ip); ip[16] = '\0'; if(strcmp(ip, "MASTER") == 0) strcpy(ip, MASTER); info.sin_addr.s_addr = inet_addr(ip); //Conectar if(connect(sock, (SOCKADDR*)&info, sizeof(info)) == -1) { perror("connect"); return 0; } printf("Conectado!\n"); int ok=0; do { printf("Diretorio a ser transferido: "); fflush(stdin); scanf("%s", diretorio); if(strlen(diretorio) > MAX_DIR) { printf("Nome do diretorio muito grande!\n"); } ok = 1; }while(!ok); printf("Enviando requisicao de diretorio\n"); if(send(sock, diretorio, strlen(diretorio), 0) <= 0) { printf("Falha ao enviar diretorio!\n"); perror("send"); return 0; } printf("Requisicao enviada!"); printf("Aguardando resposta...\n"); //teste para ver como a resposta chega while(recv(sock, buffer, BYTES_POR_VEZ, 0) > 0) { printf("%s", buffer); } return 0; } Edited April 4, 2013 at 02:30 PM by brunoais geshi
pikax Posted April 4, 2013 at 02:03 PM Report #501612 Posted April 4, 2013 at 02:03 PM Porque que estas a usar versoes diferentes de sockets?? Usa portas diferentes para o cliente e para o server Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender. A beleza de um código está em decompor problemas complexos em pequenos blocos simples. "learn how to do it manually first, then use the wizzy tool to save time." "Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."
Shoxsz Posted April 4, 2013 at 02:06 PM Author Report #501614 Posted April 4, 2013 at 02:06 PM a sim, as versões eu troquei pra testar a diferença, mas ainda sim se forem iguais dava erro, mas as portas são as mesmas, a constante definida la em cima-> PADRAO(4700)
HappyHippyHippo Posted April 4, 2013 at 03:00 PM Report #501632 Posted April 4, 2013 at 03:00 PM então tens ai o problema ... as aplicações necessitam de correr em portas diferentes é normal deixar o sistema operativo deixar escolher uma porta aleatória para o cliente, visto este não necessitar de uma porta específica IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Shoxsz Posted April 4, 2013 at 10:43 PM Author Report #501723 Posted April 4, 2013 at 10:43 PM (edited) elas devem usar a mesma porta para comunicação, eu troquei as portas e ele nem chegam a se conectar, o meu problema é na leitura dos dados. Edited April 4, 2013 at 10:46 PM by Shoxsz
HappyHippyHippo Posted April 4, 2013 at 10:49 PM Report #501725 Posted April 4, 2013 at 10:49 PM elas devem usar a mesma porta para comunicação, eu troquei as portas e ele nem chegam a se conectar, o meu problema é na leitura dos dados. errado, não podes ter duas aplicações penduradas na mesma porta ... se não obtiveste ligação com a alteração é porque usaste uma porta já em uso IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Shoxsz Posted April 5, 2013 at 10:40 PM Author Report #501913 Posted April 5, 2013 at 10:40 PM então eu devo conectar o meu cliente na porta 30000(por exemplo) e o servidor na porta 28000(por exemplo)?
HappyHippyHippo Posted April 5, 2013 at 10:59 PM Report #501915 Posted April 5, 2013 at 10:59 PM se estiveres a correr na mesma máquina, sim. IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Shoxsz Posted April 6, 2013 at 08:53 AM Author Report #501925 Posted April 6, 2013 at 08:53 AM co um port scanner encontrei dus portas que não estavam em uso, tentei conectar por elas, mas não funcionou, as portas são: 39040 para o servidor e 39039 para o cliente
HappyHippyHippo Posted April 6, 2013 at 03:12 PM Report #501959 Posted April 6, 2013 at 03:12 PM estive a ver melhor o teu código ... à definição PADRAO que tens tem significados diferentes nas duas aplicações - servidor : porta em que o servidor se encontra à escuta - cliente : porta do servidor conclusão : sim, necessitas de ter os dois valores iguais IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Shoxsz Posted April 6, 2013 at 04:57 PM Author Report #501974 Posted April 6, 2013 at 04:57 PM sim é a porta por onde eles irao se comunicar, e elas são iguais...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now