请帮助我这个程序应该通过套接字发送文件,但当我运行它时,它显示了错误分段错误。服务器使用线程来实现多个客户端。谢谢这是我的最后一个项目!!
这是服务器代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<pthread.h>
static const int BUFFER_SIZE = 1024;
//CREAR HILO
void *connection_handler(void *);
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
//CREAR SOCKET
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1) //ERROR AL CREAR EL SOCKET
{
printf("ERROR AL CREAR EL SOCKET");
}
puts("SOCKET CREADO"); //SOCKET CREADO
//VALORES DEL SOCKET
server.sin_family = AF_INET; //SOCKET IP
server.sin_addr.s_addr = INADDR_ANY; // EJECUTAR CON LA IP DE LA MAQUINA ACTUAL
server.sin_port = htons(9999);//PUERTO
//ASOCIAR SOCKET A UN PUERTO
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
// ERROR EN LA ASOCIACION
perror("ERROR AL ASOCIAR EL SOCKET AL PUERTO DEL SERVER");
return 1;
}
puts("PUERTO CREADO EN EL SERVER CORRECTAMENTE");
//MODO ESCUCHA CONEXIONES ENTRANTES
listen(socket_desc , 3); // TRES CONEXIONES PERMITIDAS
//ACEPTA CONEXIONES ENTRANTES
puts("A LA ESPERA DE CONEXIONES ENTRANTES");
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) ) // CONEXION ACEPTADA
{
puts("CONEXION ACEPTADA");
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = client_sock;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("NO SE PUDO CREAR EL THREAD");
return 1;
}
}
if (client_sock < 0)
{
perror("FALLO");
return 1;
}
return 0;
}
/*
* HABILITAR VARIAS CONEXIONES
* */
void *connection_handler(void *socket_desc)
{
//SOCKET
int sock = *(int*)socket_desc;
char buf[BUFFER_SIZE];
while(1)
{
FILE * fpIn = fopen("/mnt/SHARED/La.Lista.De.Schindler.Latino.avi", "r"); //ARCHIVO A ENVIAR
ssize_t bytesRead = fread(buf, 1, sizeof(buf), fpIn);
if (bytesRead <= 0) break; // EOF
printf("Se han leido %i bytes del archivo, enviandolos ...n", (int)bytesRead);
if (send(sock, buf, bytesRead, 0) != bytesRead) // ENVIAR EN EL SOCKET
{
perror("AL ENVIAR!!");
break;
}
}
//LIBERAR EL SOCKET
free(socket_desc);
return 0;
}
这是客户端代码
#include<stdio.h> //printf
#include<string.h> //strlen
#include<sys/socket.h> //socket
#include<arpa/inet.h> //inet_addr
static const int BUFFER_SIZE = 16*1024;
int main(int argc , char *argv[])
{
int sock;
struct sockaddr_in server;
//CREAR SOCKET
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("NO SE PUDO CREAR EL SOCKET");
}
puts("EL SOCKET FUE CREADO");
server.sin_addr.s_addr = inet_addr("127.0.0.1"); // IP SERVER
server.sin_family = AF_INET;//SOCKET IP
server.sin_port = htons(9999); //PUERTO
//CONECTAR AL SERVER
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("LA CONEXION FALLO");
return 1;
}
puts("CONEXION ESTABLECIDAn");
FILE * fpIn = fopen("/home/soporte/PELI", "w");//ARCHIVO RECIBIDO
if (fpIn)
{
char buf[BUFFER_SIZE];
while(1)
{
ssize_t bytesReceived = recv(sock, buf, sizeof(buf), 0);
if (bytesReceived < 0) perror("RECEPCION"); //ERROR AL RECIBIR
if (bytesReceived == 0) break; //SE CIERRA LA CONEXION AL FINAL DEL ARCHIVO
printf("Se han recibido %i bytes desde la red, escribiendo a un archivo...n", (int) bytesReceived);
if (fwrite(buf, 1, bytesReceived, fpIn) != (size_t) bytesReceived)
{
perror("fwrite");
break;
}
}
fclose(fpIn);
}
else printf("Error, no se pudo abrir el archivo [%s]n", "/home/soporte/ESTEBAN");
close(sock);
return 0;
}
在服务器代码中,您可以在while....loop
中连续打开文件。这有什么用吗?
服务器中的处理程序如下所示
/*
* HABILITAR VARIAS CONEXIONES
* */
void *connection_handler(void *socket_desc)
{
//SOCKET
int sock = *(int*)socket_desc;
char buf[BUFFER_SIZE];
FILE * fpIn = fopen("/mnt/SHARED/La.Lista.De.Schindler.Latino.avi", "r");
while(1)
{
//ARCHIVO A ENVIAR
ssize_t bytesRead = fread(buf, 1, sizeof(buf), fpIn);
if (bytesRead <= 0) break; // EOF
printf("Se han leido %i bytes del archivo, enviandolos ...n", (int)bytesRead);
if (send(sock, buf, bytesRead, 0) != bytesRead) // ENVIAR EN EL SOCKET
{
perror("AL ENVIAR!!");
break;
}
}
//LIBERAR EL SOCKET
free(socket_desc);
fclose(fpIn);
return 0;
}
更改
new_sock = malloc(1);
对于
new_sock = malloc(sizeof(*new_sock));
并确保在connection_handler函数中,当您尝试打开文件时,您确实做到了。(fpIn>0)否则,你应该休息一下。