Linux下基于Socket文件传送程序设计
一、设计目的
1.掌握Linux网络开发知识。
2.掌握课题的设计步骤和方法。
3.提高Linux下c程序设计的能力。
4.掌握应用程序开发中的需求分析与方法。
二、设计分析
本设计是在Linux环境下基于Socket进行开发的。系统有一个服务器端和两个客户端组成。先是运行服务器等待两个客户端的连接请求,客户端1和客户端2分别登入到服务器上,登入成功后服务器会分别给客服端发送登陆成功提示。此时客户端1便可将指定文件里德内容打开,发送到服务器上,服务器接收后再将之转发给客户端2,接着客户端2新建一个文件,并将接收到的由服务器转发的内容写入到该文件中,由此便实现了不同客户端之间的文件传送。
三、系统设计
1.系统功能
1)开启服务器;
2)两个客户端登入服务器;
3)客户端1打开文件并传给服务器;
4)服务器将接收到的内容传给客户端2;
5)客户端2新建文件并保持收到的内容。
2.相关文件
fuwuqi.c是服务器源代码,kehuduan1.c是客户端1源代码,kehuduan2.c是客户端2源代码,fuwuqi是服务器执行文件,kehuduan1是客户端1执行文件,kehuduan2是客户端2执行文件,xshy.c是所要传送的文件,rec是接收文件所在的文件夹。
四、调试结果
服务器
客户端1
客户端2
五、设计总结
经过本次程序设计,提高了我在Linux下用C语言编写程序的能力,掌握了网络Socket 编程,了解了有关网络方面的知识。本来是想设计双方都可以发送接收的,奈何能力不足,错误多多,暂时就只能先实现简单的一方发送一方接收,接下来会思考下如何进一步改善。
附录
1.fuwuqi.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVPORT 2012 //端口号
#define BACKLOG 10 //最大请求数
#define MAX_CONNECTED_NC 10
#define MAXDATASIZE 64 //缓冲区长度
#define FILE_NAME_MAX_SIZE 512
int main()
{
struct sockaddr_in fuwuqi_sockaddr,kehuduan1_sockaddr,kehuduan2_sockaddr;
int sin_size,shoudaozijieshu;
int fuwuqi_fd,kehuduan1_fd,kehuduan2_fd;
int wenjian_open,wenjian_write;
char buf[MAXDATASIZE],temp[MAXDATASIZE],*IP1,*IP2;
char *filename;
if((fuwuqi_fd=socket(AF_INET,SOCK_STREAM,0))==-1) //建立服务器socket连接{
perror("socket");
exit(1);
}
printf("socket success!\n");
//设置server_sockaddr相关参数
fuwuqi_sockaddr.sin_family=AF_INET;
fuwuqi_sockaddr.sin_port=htons(SERVPORT);
fuwuqi_sockaddr.sin_addr.s_addr=INADDR_ANY;
bzero(&(fuwuqi_sockaddr.sin_zero),8);
//服务器绑定
if(bind(fuwuqi_fd,(struct sockaddr*)&fuwuqi_sockaddr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
printf("bind success!\n");
if (listen(fuwuqi_fd,BACKLOG)==-1) )//服务器监听
{
perror("listen");
exit(1);
}
printf("listening...\n");
sin_size=sizeof(struct sockaddr);
//等待客户1连接
if((kehuduan1_fd=accept(fuwuqi_fd,(struct
sockaddr*)&kehuduan1_sockaddr,&sin_size))==-1)
{
perror("accept:");
exit(1);
}
else
{
memset(temp,0,sizeof(temp));
strcpy(temp,"success to log in the server!");
//等待客户2连接
if(send(kehuduan1_fd,temp,MAXDA TASIZE,0)==-1)
{
perror("send");
exit(1);
}
}
if((kehuduan2_fd=accept(fuwuqi_fd,(struct
sockaddr*)&kehuduan2_sockaddr,&sin_size))==-1)
{
perror("accept:");
exit(1);
}
else
{
memset(temp,0,sizeof(temp)); //从客户1接收文件内容
strcpy(temp,"success to log in the server!");
if(send(kehuduan2_fd,temp,MAXDA TASIZE,0)==-1)
{
perror("send");
exit(1);
}
}
memset(temp,0,sizeof(temp)); //向客户2转发接收到的内容
strcpy(temp,"You friend has on-line,you can send/accept now!");
if((send(kehuduan1_fd,temp,MAXDA TASIZE,0)==-1)||(send(kehuduan2_fd,temp,MAXDA T ASIZE,0)==-1))
{
perror("send");
exit(1);
}
printf("file upload server starting...\n");
memset(buf,0,sizeof(buf));
if((shoudaozijieshu=recv(kehuduan1_fd,buf,MAXDATASIZE,0))==-1)
{
perror("recv");
exit(1);
}
printf("buf:%s\n",buf);
if(send(kehuduan2_fd,buf,MAXDATASIZE,0)==-1)
{
perror("send");
exit(1);
}
printf("file upload success!\n");
close(wenjian_open);
close(fuwuqi_fd);
}
2.kehuduan1.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVPORT 2012 //端口号
#define MAXDATASIZE 64 //缓冲区长度
int main(int argc,char *argv[])
{
int kehuduan1_fd,fasongzijieshu,shoudaozijieshu;
int wenjian_open,wenjian_read;
char buf[MAXDATASIZE];
char *filename,*p;
struct hostent *host;
struct sockaddr_in kehuduan1_sockaddr;
void my_recvmsg(int shoudaozijieshu,int kehuduan1_fd,char *buf);
if(argc<2)
{
fprintf(stderr,"please enter the huwuqi's hostname!\n");
exit(1);
}
if((host=gethostbyname(argv[1]))==NULL) //地址解析函数
{
perror("gethostbyname");
exit(1);
}
if((kehuduan1_fd=socket(AF_INET,SOCK_STREAM,0))==-1) //建立客户1连接
{
perror("socket");
exit(1);
}
memset(&kehuduan1_sockaddr,0,sizeof(kehuduan1_sockaddr));
//设置client_sockaddr相关参数
kehuduan1_sockaddr.sin_family=AF_INET;
kehuduan1_sockaddr.sin_port=htons(SERVPORT);
kehuduan1_sockaddr.sin_addr.s_addr=INADDR_ANY;
bzero(&(kehuduan1_sockaddr.sin_zero),8);
if(connect(kehuduan1_fd,(struct sockaddr*)&kehuduan1_sockaddr,sizeof(struct sockaddr))==-1)
{
perror("connect");
exit(1);
} //主动发起对服务器的连接请求
printf("start connecting...\n");
my_recvmsg(shoudaozijieshu,kehuduan1_fd,buf); //接收登入连接信息
my_recvmsg(shoudaozijieshu,kehuduan1_fd,buf); //接收开始聊天信息
filename="/home/zyf/lbq/xshy.c";
if ((wenjian_open=open(filename,O_RDONL Y))==-1) //打开所要发送的文件
{
perror("open will upload file");
exit(1);
}
memset(buf,0,sizeof(buf)); //将所要发送的内容写入buf if((wenjian_read=read(wenjian_open,buf,MAXDA TASIZE))==-1)
{
perror("read will upload file");
exit(1);
}
printf("%s\n",buf);
//客户1向服务器发送文件内容
if((fasongzijieshu=send(kehuduan1_fd,buf,MAXDA TASIZE,0))==-1)
{
perror("send");
exit(1);
}
printf("file has been uploaded successfully!\n");
close(wenjian_open);
close(kehuduan1_fd);
}
void my_recvmsg(int shoudaozijieshu,int kehuduan1_fd,char *buf) //接收信息函数{
memset(buf,0,sizeof(buf));
if((shoudaozijieshu=recv(kehuduan1_fd,buf,MAXDATASIZE,0))==-1)
{
perror("recv");
exit(1);
}
else
{
printf("%s\n",buf);
}
}
3.kehuduan2.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVPORT 2012 //端口号
#define MAXDATASIZE 64 //缓冲区长度
int main(int argc,char *argv[])
{
int kehuduan2_fd,fasongzijieshu,shoudaozijieshu;
int wenjian_open,wenjian_write,wenjian_read;
char buf[MAXDATASIZE];
char *filename,*p;
struct hostent *host;
struct sockaddr_in kehuduan2_sockaddr;
void my_recvmsg(int shoudaozijieshu,int kehuduan2_fd,char *buf);
if(argc<2)
{
fprintf(stderr,"please enter the huwuqi's hostname!\n");
exit(1);
}
if((host=gethostbyname(argv[1]))==NULL) //地址解析函数
{
perror("gethostbyname");
exit(1);
}
if((kehuduan2_fd=socket(AF_INET,SOCK_STREAM,0))==-1) //建立客户2连接{
perror("socket");
exit(1);
}
memset(&kehuduan2_sockaddr,0,sizeof(kehuduan2_sockaddr));
//设置client_sockaddr相关参数
kehuduan2_sockaddr.sin_family=AF_INET;
kehuduan2_sockaddr.sin_port=htons(SERVPORT);
kehuduan2_sockaddr.sin_addr.s_addr=INADDR_ANY;
bzero(&(kehuduan2_sockaddr.sin_zero),8);
if(connect(kehuduan2_fd,(struct sockaddr*)&kehuduan2_sockaddr,sizeof(struct sockaddr))==-1)
{
perror("connect");
exit(1);
}
printf("start connecting...\n"); //主动发起对服务器的连接请求
my_recvmsg(shoudaozijieshu,kehuduan2_fd,buf); //接收登入连接信息
my_recvmsg(shoudaozijieshu,kehuduan2_fd,buf); //接收开始聊天信息
filename="/home/zyf/lbq/rec/xshy.c"; //客户2新建文件
if((wenjian_open=open(filename,O_CREAT|O_TRUNC|O_WRONL Y,0644))==-1)
{
perror("open localhost file");
exit(1);
}
memset(buf,0,sizeof(buf)); //客户2接收从服务器转发过来的客户1的文件内容if((shoudaozijieshu=recv(kehuduan2_fd,buf,MAXDATASIZE,0))==-1)
{
perror("recv");
exit(1);
}
printf("buf:%s\n",buf);
//客户2讲接收到的内容写入新建文件中
if(wenjian_write=write(wenjian_open,buf,sizeof(buf))==-1)
{
perror("writting to file error");
exit(1);
}
printf("file has been uploaded successfully!\n");
close(wenjian_open);
close(kehuduan2_fd);
}
void my_recvmsg(int shoudaozijieshu,int kehuduan2_fd,char *buf) //接收信息函数
{
memset(buf,0,sizeof(buf));
if((shoudaozijieshu=recv(kehuduan2_fd,buf,MAXDATASIZE,0))==-1)
{
perror("recv");
exit(1);
}
else
{
printf("%s\n",buf);
}
}