Tema destacado: Deseas probar algunas mejoras a la interfaz del foro? Prueba cake! acerca de
Autor
|
Tema: Imperfeccion en la transmisión con sockets de flujo. (Leído 1,218 veces)
|
tuket
Desconectado
Mensajes: 91
01110100 01110101 01101011 01100101 01110100
|
He hecho 2 programas de sockets en C++. Consiste enviar la cadena "hola" desde un ordenador a otro y hacer que lo muestre en la pantalla del otro ordenador. Lo he conseguido hacer pero el problema es que el 80% de las veces los datos llegan corruptos. Esto me extraña por que según tengo yo entendido los sockets de flujo usan el protocolo TCP y en este protocolo es el mismo el que se encarga de que lleguen los resultados adecuadamente. ¿Por que sucede esto?¿Como se puede evitar?
Datos: un ordenador es linux y el otro es windows. No estoy usando datagramas.
|
|
|
|
« Última modificación: 4 Enero 2011, 14:19 por tuket »
|
En línea
|
|
|
|
Garfield07
Desconectado
Mensajes: 1.123
¡Este año voy a por todas! JMJ 2011
|
Si pero podrias poner el code?
|
|
|
|
|
En línea
|
 * Quiero cambiar el mundo, pero estoy seguro de que no me darían el código fuente. * No estoy tratando de destruir a Microsoft. Ese será tan solo un efecto colateral no intencionado. * Si compila esta bien, si arranca es perfecto. ¡Wiki elhacker.net!Un saludo
|
|
|
tuket
Desconectado
Mensajes: 91
01110100 01110101 01101011 01100101 01110100
|
Si, claro(aunque no creo que sea necesario): 1º: #include<iostream> #include<string.h> #include<stdio.h> #include<sys/types.h> #include<winsock.h> #include<conio.h> int main(){ { WSADATA wsaData; /* Si esto no funciona */ //WSAData wsaData; /* prueba esto en su lugar */ if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) { fprintf(stderr, "WSAStartup failed.\n"); exit(1); } } /////////////////////////////////////////////////////////////////// struct sockaddr_in my_addr, they_addr; SOCKET sockfd, newfd; sockfd=socket(AF_INET,SOCK_STREAM,0); if(sockfd==-1){ printf("error en socket"); std::cin.get(); exit(-1); } my_addr.sin_family = AF_INET; my_addr.sin_port = htons(54332); if(my_addr.sin_addr.s_addr = htonl(INADDR_ANY)==-1){ printf("error en ip\n"); std::cin.get(); exit(-1); } memset(&(my_addr.sin_zero), '\0', 8); if(bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))==-1){ printf("error en bind()"); std::cout<<WSAGetLastError()<<std::endl; std::cin.get(); exit(-1); } if(listen(sockfd, 10)==-1){ printf("error en listen()"); getch(); exit(-1); } int size_sockaddr=sizeof(sockaddr); newfd=accept(sockfd,(struct sockaddr *)&they_addr, &size_sockaddr); int bytes_sent; //send(newfd, "hola", 5, 0); do{bytes_sent=send(newfd, "hola", 5, 0);} while (bytes_sent!=5); WSACleanup(); printf("todo en orden\n"); getchar(); } 2º: #include<stdio.h> #include<iostream> #include<string.h> #include<arpa/inet.h> #include<sys/types.h> #include<netinet/in.h> int main(){ int sockfd; struct sockaddr_in dest_addr; sockfd=socket(AF_INET, SOCK_STREAM, 0); if(sockfd==-1){ printf("error en el socket"); std::cin.get(); return -1; } dest_addr.sin_family=AF_INET; dest_addr.sin_port=htons(54332); dest_addr.sin_addr.s_addr=inet_addr("192.168.1.112"); if(dest_addr.sin_addr.s_addr==-1){ printf("error en ip"); getchar(); return -1; } memset(&(dest_addr.sin_zero),0, 8); if(connect(sockfd, (struct sockaddr*)&dest_addr, sizeof(struct sockaddr))==-1){ printf("error en conect"); getchar(); return -1; } char cadena[5]; recv(sockfd, &cadena, 5, 0); cadena[4]=0; std::cout<<cadena<<std::endl; printf("todo en orden\n"); }
|
|
|
|
« Última modificación: 4 Enero 2011, 20:11 por tuket »
|
En línea
|
|
|
|
Garfield07
Desconectado
Mensajes: 1.123
¡Este año voy a por todas! JMJ 2011
|
¿Y por que no lo has puesto en el foro de C/C++? PD: Luego miro el code que ahora voy a jugar un poquito 
|
|
|
|
|
En línea
|
 * Quiero cambiar el mundo, pero estoy seguro de que no me darían el código fuente. * No estoy tratando de destruir a Microsoft. Ese será tan solo un efecto colateral no intencionado. * Si compila esta bien, si arranca es perfecto. ¡Wiki elhacker.net!Un saludo
|
|
|
tuket
Desconectado
Mensajes: 91
01110100 01110101 01101011 01100101 01110100
|
Por que a pesar de estar escrito en C++ la duda no tiene que ver en absoluto con C++. Tiene que ver con la programación de sockets. xD
|
|
|
|
|
En línea
|
|
|
|
Garfield07
Desconectado
Mensajes: 1.123
¡Este año voy a por todas! JMJ 2011
|
Exactamente  Necesitaria ver el code para ver si tiene algo que lo provoque. Los sockets se acaban al compilar xD no tienen vuelta de hoja...
|
|
|
|
|
En línea
|
 * Quiero cambiar el mundo, pero estoy seguro de que no me darían el código fuente. * No estoy tratando de destruir a Microsoft. Ese será tan solo un efecto colateral no intencionado. * Si compila esta bien, si arranca es perfecto. ¡Wiki elhacker.net!Un saludo
|
|
|
Khronos14
Desconectado
Mensajes: 285
A lie is a lie
|
Hola tuket, yo probaría a enviar los datos de esta forma para ver si es este el problema. char buff[] = "hola"; send(newfd, buff, 5, 0); Si tengo tiempo, luego pruebo los programas. Saludos.
|
|
|
|
|
En línea
|
|
|
|
Garfield07
Desconectado
Mensajes: 1.123
¡Este año voy a por todas! JMJ 2011
|
Podrias empezar mirando codes de sockets que hay en el foro de C/C++
|
|
|
|
|
En línea
|
 * Quiero cambiar el mundo, pero estoy seguro de que no me darían el código fuente. * No estoy tratando de destruir a Microsoft. Ese será tan solo un efecto colateral no intencionado. * Si compila esta bien, si arranca es perfecto. ¡Wiki elhacker.net!Un saludo
|
|
|
tuket
Desconectado
Mensajes: 91
01110100 01110101 01101011 01100101 01110100
|
Hola, gracias por responder. Hola tuket, yo probaría a enviar los datos de esta forma para ver si es este el problema.
Código char buff[] = "hola"; send(newfd, buff, 5, 0);
Si tengo tiempo, luego pruebo los programas.
Saludos. Eso ya lo probé, pasa lo mismo: la gran mayoría de las veces los datos llegan corruptos. Yo intuyo que se debe de hacer alguna comprobación pero no se.
|
|
|
|
|
En línea
|
|
|
|
Garfield07
Desconectado
Mensajes: 1.123
¡Este año voy a por todas! JMJ 2011
|
|
|
|
|
|
En línea
|
 * Quiero cambiar el mundo, pero estoy seguro de que no me darían el código fuente. * No estoy tratando de destruir a Microsoft. Ese será tan solo un efecto colateral no intencionado. * Si compila esta bien, si arranca es perfecto. ¡Wiki elhacker.net!Un saludo
|
|
|
tuket
Desconectado
Mensajes: 91
01110100 01110101 01101011 01100101 01110100
|
Bueno. Ya que nadie entiende lo que se pregunta lo voy a repetir de otra manera. Segun wikipedia: TCP El protocolo garantiza que los datos serán entregados en su destino sin errores y en el mismo orden en que se transmitieron. Lo que significa que si envió los datos por TCP tienen que llegar seguro correctamente. Como dice esta pagina( http://www.fismat.umich.mx/mn1/manual/node24.html):Socket de flujo da un flujo de datos de dos vías, confiable, y sin duplicados sin límites de grabación. El flujo opera en forma parecida a una conversación telefónica. El tipo del socket es SOCK_STREAM, el cual en el dominio de Internet usa TCP (Transmission Control Protocol). SOCK_STREAM usa el protocolo TCP lo que significa que la cadena "hola" tiene que llegar por cojones al ordenador opuesto(de hecho en ocasiones si que llega). Mi pregunta es: ¿Por que demonios no llega?¿Se debe a la recepción?¿Wikipedia miente?¿Hay interferencias?¿los extraterrestres están jodiéndome manipulando los datos? XD espero que ahora se entienda mejor PD: gracias por el link Sagrini pero no se a que viene eso.
|
|
|
|
« Última modificación: 4 Enero 2011, 23:31 por tuket »
|
En línea
|
|
|
|
Khronos14
Desconectado
Mensajes: 285
A lie is a lie
|
tuket, el protocolo TCP/IP no falla. Lo que falla son los programas, o el cliente o el servidor.
Saludos.
|
|
|
|
|
En línea
|
|
|
|
|
|
ukol
Desconectado
Mensajes: 31
|
Te faltó cerrar el socket(closesocket/shutdown en wsock) quizá sea eso(código 1). http://msdn.microsoft.com/en-us/library/bb530744%28v=VS.85%29.aspxEdito: Por cierto, en el segundo código no miras si da error, si devuelve -1 miras el errno con strerror(errno) y te hubiera dado mas información de lo que pasa. Que lo sepas pa la próxima, en windows no se como se hace pero seguro hay forma.
|
|
|
|
« Última modificación: 5 Enero 2011, 18:19 por ukol »
|
En línea
|
|
|
|
tuket
Desconectado
Mensajes: 91
01110100 01110101 01101011 01100101 01110100
|
Nada ya esta solucionado dejo el código cambiado por si a alguien le interesa: #include<windows.h> #include<iostream> #include<string.h> #include<stdio.h> #include<sys/types.h> #include<winsock.h> #include<conio.h> int main(){ { WSADATA wsaData; /* Si esto no funciona */ //WSAData wsaData; /* prueba esto en su lugar */ if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) { fprintf(stderr, "WSAStartup failed.\n"); exit(1); } } /////////////////////////////////////////////////////////////////// struct sockaddr_in my_addr, they_addr; SOCKET sockfd, newfd; sockfd=socket(AF_INET,SOCK_STREAM,0); if(sockfd==-1){ printf("error en socket"); std::cin.get(); exit(-1); } my_addr.sin_family = AF_INET; my_addr.sin_port = htons(54336); if(my_addr.sin_addr.s_addr = htonl(INADDR_ANY)==-1){ printf("error en ip\n"); std::cin.get(); exit(-1); } memset(&(my_addr.sin_zero), '\0', 8); if(bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))==-1){ printf("error en bind()"); std::cout<<WSAGetLastError()<<std::endl; std::cin.get(); exit(-1); } if(listen(sockfd, 10)==-1){ printf("error en listen()"); getch(); exit(-1); } int bytes_sent; int size_sockaddr=sizeof(sockaddr); while(1){ newfd=accept(sockfd,(struct sockaddr *)&they_addr, &size_sockaddr); //send(newfd, "hola", 5, 0); bytes_sent=send(newfd, "mola", 5, 0); closesocket(newfd); } WSACleanup(); printf("todo en orden\n"); getchar(); }
|
|
|
|
|
En línea
|
|
|
|
|
|