2011-01-31 8 views
5

Estoy tratando de pensar en la mejor manera de enviar un archivo de video a través de un socket TCP. He hecho un programa de socket estándar, pero después del comando read no estoy seguro de cómo puedo guardarlo.Mejor manera de enviar video a través de Socket TCP en C

Ejemplo de código

//bind server socketfd 
if (bind(sfdServer, (struct sockaddr*)&adrServer, ServerAddrLen) < 0) 
    error("ERROR binding"); 
listen(sfdServer, 5); 
while(1){ 
    printf("Waiting for connections...\n"); 
    sfdClient = accept(sfdServer, (struct sockaddr*)&adrClient, &ClientAddrLen); 
    if(sfdClient < 0) 
     error("ERROR accepting"); 

    printf("Connection Established.\n"); 
    //set buffer to zero   
    bzero(buff, 2048); 
    printf("Reading from client.\n"); 
    numChar = read(sfdClient, buff, 2048); 

    //What should go here? 

    close(sfdClient); 
    close(sfdServer); 

} 

¿Me acaba de guardar el búfer como un archivo movie.mp4 o algo por el estilo? Me doy cuenta de que podría necesitar cambiar mi tamaño de búfer o posiblemente enviarlo en pedazos. Pero no puedo encontrar ninguna buena información sobre la mejor manera de hacer esto. ¡Cualquier ayuda o un punto en la dirección correcta sería apreciada!

Respuesta

3

Escribirá los fragmentos del búfer en un archivo.

primer lugar, abrir un archivo de salida para la escritura:

#include <sys/types.h> 
    #include <sys/stat.h> 
    #include <fcntl.h> 


    int outfd; 
    outfd = open("movie.mp4", O_WRONLY|); 

Luego, después de la read(), escribir sus bytes:

numWrite = write(outfd, buff, numChar); 

Tenga en cuenta que tendrá que hacer frente a una serie de fragmentación/casos de tamponamiento, tales como:

  • o bien el read() o la write() que devuelve cero o -1 (error)
  • Lectura hasta que no haya más bytes disponibles. En este momento, su código solo lee 2048 bytes y luego cierra el socket.
  • El write() escribir un menor número de bytes que hubieran solicitado (esto puede suceder en sistemas de archivos de red)
+0

Ok usando esta información pude resolver todo. A partir de ahora puedo transferir texto desde un cliente java a este servidor C. Pero a medida que lo tenga, supongo que siempre que descargue el búfer correctamente cuando reciba datos del cliente, ¿debería transferir un archivo de video de la misma manera? –

+1

Si entiendo su pregunta correctamente, sí: para cada búfer (por ejemplo, de 2048 o menos bytes) que reciba, si lo escribe en su archivo hasta que no reciba más bytes, todo debería funcionar. A la conexión de red y al conector no le importa si es de texto o binario. – payne

2

En primer lugar, se debe considerar el uso de sendfile() o el equivalente para el sistema. Es decir, en lugar de leer un trozo del archivo en su memoria solo para volver a escribirlo en alguna parte, debe mapear la memoria del descriptor de archivo y enviarlo todo de una vez.

En cuanto a la fragmentación, TCP se encarga de dividir la secuencia en paquetes para usted. Idealmente, el nodo remoto debe saber exactamente cuánto esperar por adelantado para que pueda manejar la terminación prematura (es por eso que los encabezados HTTP contienen una longitud de contenido).

Así que use algún tipo de apretón de manos antes de enviar los datos. Luego, el emisor debe simplemente llamar al sendfile() en un bucle, prestando atención a la cantidad de datos enviados y al offet devuelto. El receptor debe llamar al recv() en un bucle para asegurarse de que llegue todo (no hay un estándar "recvfile()").

+0

+1, acepto, sendfile() se creó para simplificar este dolor de cabeza y se debe usar si está disponible, similar a elegir poll() sobre select(). Desafortunadamente, no todas las plataformas los tienen. –

+0

Agradezco la entrada, desafortunadamente la aplicación del cliente estará en Java ya que viene de un dispositivo Android. Entonces enviar archivo no es posible. –

Cuestiones relacionadas