#include "stdio.h"
#include "WinSock2.h"
#pragma comment(lib,"Ws2_32.lib")
const int
MYPORT=20000; //服务器监听的端口号
const int
QLEN=5; //监听队列的长度
const int
BUFLEN=1000; //缓冲区的大小
const int
FNLEN=200; //文件名的最大长度
int main()
{
SOCKET listenSock; //监听套接字
SOCKET
clientSock; //接受客户接入的套接字
struct sockaddr_in
saddr; //本机地址(服务器地址)
struct sockaddr_in
daddr; //对方地址(客户方地址)
char
buf[BUFLEN]; //缓冲区
char
filename[FNLEN]; //要传输到客户端的文件的文件名
char *p;
int
n; //接收到的数据长度
int
fnlen; //文件名的长度
int
aLen; //套接字地址长度
long
code; //响应码
FILE
*fp; //指向要发送给客户端的文件的文件指针
// 初始化WinSock
WORD
wVersionRequested;
WSADATA wsaData;
wVersionRequested=MAKEWORD(1,1);
if(WSAStartup(wVersionRequested,&wsaData))
{
printf("Start Socket
Error!\n");
return 1;
}
// 创建监听套接字,并进入到等待客户接入的状态
memset(&saddr,0,sizeof(struct
sockaddr_in));
saddr.sin_family=AF_INET;
saddr.sin_port=htons(MYPORT);
saddr.sin_addr.s_addr=htonl(INADDR_ANY); if((listenSock=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR)
{
printf("不能创建套接字!\n");
return 2;
}
if(bind(listenSock,(struct sockaddr
*)&saddr,sizeof(struct
sockaddr_in))==SOCKET_ERROR)
{
printf("绑定套接字错误!\n");
return 3;
}
if(listen(listenSock,QLEN)==SOCKET_ERROR)
{
printf("监听套接字错误!\n");
return 4;
}
else
{
printf("服务器开启,等待客户接入...\n");
}
while(true){
// 接受客户的接入
aLen=sizeof(struct sockaddr_in);
if((clientSock=accept(listenSock,(struct sockaddr
*)&daddr,&aLen))==INVALID_SOCKET)
{
printf("接受客户接入错误!\n");
return 5;
}
printf("客户接入:%s\n",inet_ntoa(daddr.sin_addr));
// 接收客户方欲获取文件的文件名,产生并发送响应码
memset(filename,0,FNLEN);
p=(char *)&fnlen;
recv(clientSock,p,sizeof(fnlen),0); //接收文件名的长度值
fnlen=ntohs(fnlen); //网络字节序转换为主机字节序
p=filename;
recv(clientSock,p,fnlen,0); //接收文件名
printf("客户方想要获取的文件是:%s\n",filename);
if((fp=fopen(filename,"rb"))==NULL) //指定的文件是否存在
{ //指定文件不存在
printf("不能打开指定的文件!\n");
code=htonl(-1); //主要字节序到网络字节序,-1表示出错
p=(char
*)&code;
send(clientSock,p,sizeof(long),0); //发送响应码
closesocket(clientSock); //关闭响应套接字
continue; //回到循环开始,处理下一个客户的请求
}
fseek(fp,0,SEEK_END); //读写指针移动到文件结尾
code=htonl(ftell(fp)); //返回当前读写指针的位置,即得到文件长度。
p=(char *)&code;
send(clientSock,p,sizeof(long),0);
//发送文件长度给客户方
// 打开文件,并把文件内容发送到客户方,然后关闭文件和套接字
rewind(fp); //文件读写指针移动到文件开头
while(!feof(fp)) //文件未结束
{
memset(buf,0,BUFLEN); //清除缓存中的内容
n=fread(buf,1,BUFLEN,fp); //读取文件内容到缓存
send(clientSock,buf,n,0); //把文件内容发送给客户方
}
fclose(fp); //关闭文件
closesocket(clientSock); //关闭连接套接字
}
closesocket(listenSock); //关闭监听套接字
WSACleanup(); //注销WinSock
return 0;
}
#include
#include
"WinSock2.h" //Winsock的头文件
#pragma comment(lib,"Ws2_32.lib") //WINSOCK库
const int
MYPORT=20000; //服务器监听的端口号
const int
BUFLEN=1000; //缓冲区的大小
const int
IPLEN=16; //点分十进制形式IP地址的最大长度
const int
FNLEN=200; //文件名的最大长度
int main()
{
SOCKET
Sock; //套接字描述符
struct sockaddr_in
daddr; //远程服务器地址(daddr)
char
buf[BUFLEN]; //接收缓冲区
char
sIP[IPLEN]; //存储点分十进制形式的IP地址
char
lofile[FNLEN]; //存储本地文件路径和文件名
char
refile[FNLEN]; //远程主机上的文件路径和文件名
char *p;
int
n; //接收到数据的长度
int
aLen; //struct
sockaddr的长度
int
fnlen; //文件长度
long
code; //返回码。小于0:出错,大于0:文件的长度
FILE
*fp; //指向本地文件的指针
//
初始化WinSock。只有在Windows操作系统下,基于WINSOCK编程时需要。
WORD
wVersionRequested;
WSADATA wsaData;
wVersionRequested=MAKEWORD(1,1);
if(WSAStartup(wVersionRequested,&wsaData))
{
printf("Start Socket
Error!\n");
return 1;
}
// 输入服务器的IP地址、欲获取文件的路径名(路径+文件名)、保存到本地的路径名。
memset(sIP,0,IPLEN);
printf("输入服务器的IP地址:");
scanf("%s",sIP);
daddr.sin_family=AF_INET;
daddr.sin_port=htons(MYPORT);
daddr.sin_addr.s_addr=inet_addr(sIP);
aLen=sizeof(struct sockaddr_in);
// 创建套接字并连接到服务器上
if((Sock=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR)
{
printf("创建套接字错误!\n");
return 2;
}
if(connect(Sock,(struct
sockaddr *)&daddr,aLen)==SOCKET_ERROR)
{
printf("不能连接到服务器!\n");
return 4;
}
else
{
printf("连接服务器成功,可以开始获取文件\n");
}
//连上服务器后输入获取的文件名
memset(refile,0,FNLEN);
printf("输入远程文件名:");
scanf("%s",refile);
memset(lofile,0,FNLEN);
printf("输入本地文件名:");
scanf("%s",lofile);
if((fp=fopen(lofile,"rb"))!=NULL) //本地文件是否存在
{
printf("指定的本地文件已存在!\n");
fclose(fp);
return 1;
}
// 发送远程文件名到服务器
fnlen=htons(strlen(refile)); //文件名长度
p=(char
*)&fnlen; //p指向存储文件名长度变量
send(Sock,p,sizeof(fnlen),0); //发送文件名的长度
send(Sock,refile,strlen(refile),0); //发送文件名
// 接收服务器的响应,并判断是否存在指定的远程文件,若远程文件存在,则显示文件长度
p=(char *)&code;
n=recv(Sock,p,sizeof(long),0);
code=ntohl(code); //网络字节转换为主机字节序
if(code<0) //出错
{
printf("不能打开远程文件!\n");
closesocket(Sock);
return 5;
}
// 接收数据并写入本地文件中
if((fp=fopen(lofile,"wb"))==NULL) //打开本地文件
{
printf("创建文件错误!\n");
return 6;
}
while((n=recv(Sock,buf,BUFLEN,0))>0) //接收数据并写入本地文件中
fwrite(buf,1,n,fp);
fclose(fp); //
closesocket(Sock); //关闭套接字
WSACleanup(); //注销WinSock库
return 0;
}