ChadiSt Ответов: 1

Программирование сокетов : отправка файла


Привет , в настоящее время я пытаюсь создать серверно-клиентское чат-приложение для школьного проекта ,однако мне не удается отправить файл. Если вы хотите выполнить приведенный ниже код :
Сервер принимает порт в качестве arg
клиент принимает IP-адрес ( 127.0.0.1, если он локальный) и порт.

Что я уже пробовал:

Этот код я использую с точки зрения сервера :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>



int sockfd,n,newsockfd;
char buffer[255];


void error(const char *msg)
{
	perror(msg);
	exit(1);
}

void ReceiveFile()
{
	FILE *fp=fopen("fichier.txt","ab+");
	n=read(newsockfd,buffer,255);
	printf("%s",buffer);
	fprintf(fp,"%s",buffer);
	fclose(fp);
}
void EnvoyerMessage() // SEND MESSAGE
{
	fgets(buffer,255,stdin);
	n=write(newsockfd,buffer,strlen(buffer));
	if(n<0)
	{
		error("ERROR writing to socket");
	}
	int i=strncmp("Bye",buffer,3);
}

void Chat()
{
	while(1)
	{
		bzero(buffer,256);
		n=read(newsockfd,buffer,255);
		if(n<0)
		{
			error("ERROR reading from socket");
		}

		if(strncmp(buffer,"/SEND",5)==0)
		{
			ReceiveFile();
		}
		printf("Client : %s\n",buffer);
		EnvoyerMessage();
	}
	close(newsockfd);
	close(sockfd);
}

void Serveur(char **argv)
{
	int portno;
	socklen_t clilen;
	struct sockaddr_in serv_addr,cli_addr;
	sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0)
	{
		error("ERROR opening socket");
	}
	bzero((char *) &serv_addr,sizeof(serv_addr));
	portno=atoi(argv[1]);
	serv_addr.sin_family=AF_INET;
	serv_addr.sin_addr.s_addr=INADDR_ANY;
	serv_addr.sin_port=htons(portno);
	if(bind(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) <0)
	{
		error("ERROR on binding");
	}
	listen(sockfd,5);
	clilen=sizeof(cli_addr);
	newsockfd=accept(sockfd,(struct sockaddr *) &cli_addr,&clilen);
	if(newsockfd < 0)
	{
		error("ERROR on accept");
	}

	if(n<0)
	{
		error("ERROR reading from socket");
	}
	Chat();
}

int main(int argc,char *argv[])
{
	if(argc<2)
	{
		fprintf(stderr,"ERROR, no port provided\n");
		exit(1);
	}
	Serveur(argv);
}


А вот и код клиентский мудрый :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/stat.h>


int sockfd,n;
char buffer[256];

void error(const char *msg)
{
	perror(msg);
	exit(0);
}
void SendFile()
{
	FILE *fp;
	fp=fopen("fichier.txt","ab+");
	fgets(buffer,255,fp);
	n=write(sockfd,buffer,255);
	fclose(fp);
}
void RecevoirMessage() // RECEIVE MESSAGE
{
	bzero(buffer,256);
	n=read(sockfd,buffer,255);
	if(n<0)
	{
		error("ERROR reading from socket");
	}
	printf("Server : %s\n",buffer);
	int i=strncmp("Bye",buffer,3);
}
void Chat()
{
	while(1)
	{
		bzero(buffer,256);
		fgets(buffer,255,stdin);
		n=write(sockfd,buffer,strlen(buffer));
		if(strncmp(buffer,"/SEND",5)==0)
		{
			
			SendFile();
		}
		if(n<0)
		{
			error("ERROR writing to socket");
		}
		RecevoirMessage();
	}
}
int ConnexionServeur(char *argv[])
{
	int portno;
	struct sockaddr_in serv_addr;
	struct hostent *server;
	portno=atoi(argv[2]);
	sockfd=socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0)
	{
		error("ERROR opening socket");
	}
	server = gethostbyname(argv[1]);
	if(server==NULL)
	{
		fprintf(stderr,"ERROR ,no such host\n");
		exit(0);
	}
	bzero((char *) &serv_addr,sizeof(serv_addr));
	serv_addr.sin_family=AF_INET;
	bcopy((char *)server->h_addr,(char*)&serv_addr.sin_addr.s_addr,server->h_length);
	serv_addr.sin_port=htons(portno);
	if(connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
	{
		error("ERROR connecting");
	}
	Chat();
}
int main(int argc,char **argv)
{

	if(argc < 3)
	{
		fprintf(stderr,"usage %s hostname port\n", argv[0]);
		exit(0);
	}
	ConnexionServeur(argv);
}


Чего я не могу понять, так это того, что когда я вызываю функции отправки / получения файлов напрямую, не проходя через чат (), это работает . Однако , как только я прохожу через чат, функция перестает работать, и я получаю пустой файл :/ .

Afzaal Ahmad Zeeshan

И в чем именно заключается проблема ?

1 Ответов

Рейтинг:
0

Rick York

Приложение, над которым я работаю, поддерживает сокетные соединения с группой подчиненных компьютеров. Мы посылаем множество различных данных через соединение, и у нас есть поле заголовка, которое идет с каждым фрагментом данных. Он имеет флаг, тип, командное поле и длину. С помощью типа и команды мы можем определить, что делать с данными. Одним из типов данных, которые мы посылаем, является фактическая программа, поэтому она может обновляться сама. Я рекомендую принять что-то подобное, чтобы вы могли различать текстовые данные из чата и данные для файла.

Еще одна вещь, которую следует иметь в виду, - это размер данных в одном пакете ethernet менее 1500 байт. Это не проблема с приложением чата, но это может быть проблемой при передаче файлов. Вам нужно будет реализовать функцию приема нескольких пакетов. Отправка многопакетного сообщения не является большой проблемой, но получение его может быть. Альтернативой является разбиение файла на патроны и отправка их один за другим. Я думаю, что лучше обрабатывать многопакетные сообщения, потому что это может быть очень полезно, как только вы это выясните.