套接字编程:发送文件 [英] Socket programming : sending a file
问题描述
我正在尝试为学校项目制作服务器 - 客户端聊天应用程序,但是我无法管理发送文件。如果你想执行下面的代码:
服务器将端口作为arg
客户端获取IP地址(如果是本地127.0.0.1)和港口。
我尝试了什么:
这个代码我使用服务器明智:
Hi , i'm currently trying to make a Server-Client Chat Application for a school project ,However i can't manage to send a file. If you'd like to execute the code below :
The server takes the port as an arg
the client takes the IP address ( 127.0.0.1 if local) and the port.
What I have tried:
This the code i'm using Server wise :
#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);
}
以下是明智的代码:
And here is the code client wise :
#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);
}
我无法弄清楚当我直接调用发送/接收文件功能而不必去通过Chat()它的工作原理。但是,一旦我通过聊天功能停止工作,我收到一个空白文件:/。
What i can't figure out is that when i call Send / Receive Files functions directly without having to go through the Chat() it works . However , as soon as i go through the chat function is stops working and i receive a blank file :/ .
推荐答案
我工作的应用程序维护套接字连接与一组奴隶电脑。我们通过连接发送各种不同的数据,并且我们有一个与每个数据一起的标题字段。它有一个标志,一个类型,一个命令字段和一个长度。通过类型和命令,我们可以确定如何处理数据。我们发送的一种数据是实际程序,因此它可以自行更新。我建议采用类似的东西,以便区分聊天中的文本数据和文件的数据。
要记住的另一件事是数据的大小单个以太网数据包小于1500字节。这不是聊天应用程序的问题,但在传输文件时可能会出现问题。您需要实现多包接收功能。发送多包消息并不是一个问题,但接收一个可以。另一种方法是将文件拆分为卡盘并逐个发送。我认为处理多包消息会更好,因为一旦你想到它就会非常有用。
The app I work on maintains socket connections with a group of slave computers. We send a variety of different data across the connection and we have a header field that goes with every piece of data. It has a flag, a type, a command field, and a length. With the type and command we can determine what to do with the data. One type of data we send is the actual program so it can update itself. I recommend adopting something similar so you can distinguish between textual data from the chat and data for a file.
One more thing to keep in mind is the size of data in a single ethernet packet is less than 1500 bytes. That is not a problem with a chat app but it can be an issue when transmitting files. You will need to implement a multiple packet receiving function. Sending a multi-packet message is not much of an issue but receiving one can be. The alternative is to split the file into chucks and send them one by one. I think it is better to handle multi-packet messages because it can be very useful once you have it figured out.
这篇关于套接字编程:发送文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!