原文是在
上发布的(好像这个地址的也是转载^_^)
不过文章中提供的源代码问题确实太多了,昨天一位网友求助让我帮其调试程序,一看,想不到竟是这片文章提供的代码,而且自己还回过贴,呵呵,真是有缘,晚上便将代码调试了一下,顺便做了些格式上的修改,相信大概的思想大家都已经明白了,今天早上调通了试了试还不错,传了个图片和应用程序,蛮快的,贴出来与大家分享一下:
(1):首先在/etc/host中添加Server地址,我的机上是这样
-
[root@localhost root]# cat /etc/hosts
-
# Do not remove the following line, or various programs
-
# that require network functionality will fail.
-
127.0.0.1 localhost.localdomain localhost
复制代码
只需要在下面的一行添加上
-
192.168.1.21 localhost.localdomain Server
复制代码
就可以了,当然,这里的192.168.1.21要改成你的server端程序所在的机子的IP地址,其次,Server
可以随便改成你喜欢的名字,阿毛阿狗都可以,只要跟后面程序中的host_name中一致就行了
下面贴出代码
服务器端,也就是文件存放端的程序
-
/**********************FileServer.c******************************/
-
//Author: May be duanjigang, ^_^
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#define command "clear"
-
//这里其实应改写成ifdef _WIN32 define command "cls" else define "clear",更合理些
-
#include
-
#define big_size 2048
-
#define small_size 50
-
int main(void)
-
{
-
char c= 0,
-
buf[big_size],//读文件的缓冲
-
file[small_size],//文件名
-
host_name[small_size];//主机名
-
int fromlen = 0,source = 0;
-
register int k,s,ns;
-
struct sockaddr_in sin;
-
struct hostent * hp;
-
system(command);//清屏
-
printf("输入要传输的文件名:");
-
memset(file, 0, small_size);
-
scanf("%s",file);
-
if ((source = open(file, O_RDONLY) ) < 0)
-
{
-
perror("源文件打开出错");
-
exit(1);
-
}
-
memset(host_name, 0, small_size);
-
//写入server的名子,然后gethostbyname将会根据这个名子去找主机的信息
-
sprintf(host_name, "%s", "Server");
-
if((hp = gethostbyname(host_name)) == NULL)
-
{
-
perror("返回主机地址信息错!!!");
-
exit(2);
-
}
-
if( (s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-
{
-
printf("获取SOCKET号失败!!!");
-
exit(3);
-
}
-
sin.sin_family=AF_INET;
-
sin.sin_port=htons(1500);
-
memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
-
if(bind(s, (struct sockaddr*)&sin, sizeof(sin)) < 0 )
-
{
-
printf("不能将服务器地址捆绑到SOCKET号上!!!\n");
-
close(s);
-
exit(4);
-
}
-
if(listen(s,5) < 0)
-
{
-
fprintf(stderr, "sever:listen\n");
-
exit(5);
-
}
-
while(1)
-
{
-
printf("等待传送文件中.......\n");
-
if((ns = accept(s, NULL, NULL)) < 0 )
-
{
-
fprintf(stderr, "sever:accept\n");
-
exit(6);
-
}
-
lseek(source,0L,0);
-
printf("开始传送文件.....\n");
-
//先把文件名发过求
-
write(ns,file,sizeof(file));
-
printf("%s\n", file);
-
//发送文件名
-
memset(buf, 0, big_size);
-
while( (k = read(source, buf, sizeof(buf))) > 0)
-
{
-
//循环发送直到,文件结束
-
write(ns,buf,k);
-
memset(buf, 0, big_size);
-
}
-
printf("\n传输完毕\n");
-
close(ns);
-
}
-
close(source);
-
exit(0);
-
}
-
[code]
-
客户端,即要下载文件的机子端程序
-
[code]
-
/*****************************FileClient.c********************************/
-
#include
-
#include
-
-
#include
-
#include
-
#include
-
#include
-
#define command "clear"
-
-
#include
-
#include
-
-
#define big_size 1024
-
#define small_size 50
-
-
int main(void)
-
{
-
char buf[big_size] ={0},file[small_size]={0},
-
host_name[small_size]={0};
-
int target,ret;
-
register int bytes,sockfd;
-
struct sockaddr_in sin ;
-
struct hostent *hp;
-
system(command);
-
sprintf(host_name, "%s", "Server");
-
if((hp = gethostbyname(host_name)) == NULL)
-
{
-
fprintf(stderr, "返回服务器地址信息错!!!\n");
-
exit(1);
-
}
-
if((sockfd = socket(AF_INET, SOCK_STREAM, 0 )) < 0)
-
{
-
fprintf(stderr, "获取SOCKET号失败!!!\n");
-
exit(2);
-
}
-
-
memset((char*)&sin, '\0', sizeof(sin));
-
-
sin.sin_family = AF_INET;
-
sin.sin_port = htons(1500);
-
-
sin.sin_addr = *(struct in_addr*)hp->h_addr;
-
if((ret = connect(sockfd, (struct sockaddr*)&sin, sizeof(sin))) == -1)
-
{
-
fprintf(stderr, "不能与服务器连接!!!\n");
-
exit(3);
-
}
-
memset(buf, 0, big_size);
-
while(read(sockfd, file, sizeof(file)) < 0);
-
sprintf(buf, "%s_%s", "receive", file);
-
-
if((target=open(buf, O_WRONLY|O_CREAT|O_TRUNC,0644)) < 0)
-
{
-
perror("不能打开目标文件!!");
-
exit(4);
-
}
-
-
memset(buf, 0, big_size);
-
while((bytes = read(sockfd, buf, sizeof(buf))) > 0)
-
{
-
write(target,buf,bytes);
-
memset(buf, 0, big_size);
-
}
-
printf("接收文件成功!!!\n");
-
close(sockfd);
-
close(target);
-
}
复制代码
后话
(1):实现windows和Linux的多平台程序,昨天在windows下调通了,可是客户端老是出错,就没做太多研究,有兴趣的朋友可以尝试一下。
(2):今天忽然想到,既然都做到这个地步了,我们为何不把它作成一个FTP程序,而且,考虑到多客户串行端传输比较费时,所以最好在accept到一个客户端的时候就生成一个线程,实现并行下载,对于FTP我也不是很懂,不过觉的这样应改可以实现吧,后面有空了一定要尝试的,在此先提一下自己的想法,有兴趣的朋友可以自己实现一下,呵呵,最近太忙了,都没时间光顾CU了,学习,学习。。。。。。。
|