基于FTP协议的WinSock程序实现

1、FTP模型

FTP协议是基于TCP/IP协议的应用层协议之一,在实际运行中,它使用两个TCP连接来完成文件传输操作,这两个TCP连接分别是控制连接和数据连接。在整个FTP处理过程中,控制连接起传输控制信息的作用,它始终保持主动状态。用户需求的数据是通过数据连接来传输的。

 

2、应用WinSock实现网络通信

    WinSock是Microsoft等公司联合开发的网络编程接口,其实是一种进程间相互通信的机制,并将这种进程间通信从单机环境扩展到网络环境,适合于开发主机/客户机通信程序。网络通信包括两台主机或者两个进程通过网络传递数据,网络的每一端称为一个端点,而WinSock为网络端点的抽象表T。当用其编程时,程序在网络对话的每端都需要一个Socket,两个Socket之间可以应用面向连接的或者是无连接的网络协议。

    面向连接的协议通过互换确认信息在连接端口之间建立一条虚电路,它不必关心网络软件传送数据。因而面向连接的客户程序不必指定本地协议端口,而只需为Socket提供远程主机信息;IP地址和协议端口,WinSock可自动保存本地IP地址和选择本地端口。

面向连接的WinSock客户机/服务器模型,服务器在没有请求到达时,它处于等待状态。一旦请求到来,服务器立即产生一个子进程,然后回到等待状态,由子进程相应请求。当下一个请求到达时,服务器再产生一个新进程。其中,并发服务器成为主服务器,子进程称为从服务器。这种主从服务器的方式巧妙地解决了并发请求问题。

 

3、程序功能

    客户机/服务器方式的服务器方的源程序为NET,用VC+ +6.0编写而成。其功能是实现服务通信功能,允许多个客户连接,响应客户请求,发送文本文件。为了解、熟悉通信过程,依据通信过程设定了菜单栏,即开始连接(侦听)、发送接收数据。服务器编程后,客户端编程可以借用,因此较简单,客户端程序为Net-Client,可以连接服务器,接收数据。测试时首先启动服务器程序,等待客户连接,建立连接后可发送文本文件,结果无误。

标准的FTP协议,功能丰富,在这里着重于客户机/服务器模型的实现,编程实现其最基本的功能建立连接及文件传输。

3.1、总体设计

模块划分

(1)侦听、建立连接模块:CListenSocket} CReceiveSocket

(2)交换消息模块:CMsg

(3)处理连接请求,发送接收数据模块:CNetView

 

实现方案

    (1)编写交换信息类,即信息内容类CMsg,使用Cobject作为基类,用于确定客户和服务器交换信息的格式和内容,其头文件为msg. h,代码文件为msg. h内音日包含如下过程:

    CMsg();构造函数

    一CMsg( );析构函数

    void Init( );初始化函数

    void Serialize(Carchive& ar);      CMsg序列化函数

    Void AssertValid()const;

    Void Dump ( CdumpContext& do )     const;   CMsg诊断函数

    通信交换信息头文件Commun. h中描述了通信双方的应答信息,包括连接信息和文件发送状态信息:

    (2)初始化WinSock库

在调用WinSock前,必须初始化WinSock库。由CnetView的消息映射函数OnInitialUpdate)完成,其中WSAStartup函数用于初始化WinSock. dll,检索WinSock执行体信息,通知WinSock分配程序所需的网络资源,指定要求的WinSock版本,它必须与WSACIeanUp成对使用。WSACIeanUp通知WinSock释放程序所需要网络资源,发送剩余数据,关闭套接字后中断连接。

(3) CSoket类

以CSoket类为基类建立两个类:

(a)侦听类ClistenSocket,用于侦听和响应用户的连接请求,建立虚电路。

主要成员如下:

ClistenSocket ( CnetView*pView);

构造函数;

这样侦听类ClistenSocket即可调用视图类的公共成员。

Void OnAccept();

(b)数据接收类CreceiveSocket,用于与用户通信,接收用户信息和发送给用户信息。

主要成员如下:

CReceiveSocket(CnetView*pView)

构造函数;

~CReceiveSocket()

析构函数;

void Initialize()

    初始化函数,实现数据接口的初始化工作;

    void OnRecieve()

    接收数据回调函数;

    void SendMsg(CMsg*pMsg)

    发送数据函数;

    void ReceiveMsg(CMsg*pMsg)

    接收数据函数;

    void Abort()

    关闭套接字的接收功能的函数

    (4 ) CNetView,处理连接请求,接收发送数据及多客户连接等。

    void OnNetServerstar()

     “开始侦听”,菜单项命令映射函数,

功能为开始侦听连接请求,等候客户连接。

在网络环境中,进程之间通信首先要解决进程标识问题。

Dlg InputPort. M_nInPort必须与客户端输入的端口号一致,它用于唯一标志通信进程。

    void OnUpdateNetServerstart(CcmdUI*pCmdUI)

     “开始侦听”,菜单项的更新用户界面函数。

    void OnListenAccept(WPARAM  wParam}LPARAM  lparam)

    处理已响应客户的连接请求的函数。

    void OnNetSendData()

    发送数据’,菜单项命令映射函数,为客户发送文件。

    void SendFile(pp Socket)

    文件发送函数。

    void OnUpdateNetSenddata ( CcmdUI*pCmdUI)

    “发送数据”,菜单项的更新用户界面函数。

    void ReceiveData(CReceiveSocket*pSocket)

    接收客户数据函数。

    CloseSocket(CReceiveSocket*pSocket)

    处理客户退出事件的函数。

    void OnDestroy()

    处理服务器关闭的退出函数。

    void OnDraw(CDC*pDC)

    显示服务器、客户交换信息的函数。

    void OnPrepareDC(CDC*pDC, CPrintInfo*pInfo)

设置显示设备环境。

 

部分程序

    (1)建立Socket对象

    Csocket*pSocket=new(Socket);

    if(!pSocket Creat())

    {

    delete pSocket;

    messageBox("Create Object Error!”,ErrorInfo", MB OIL);

return NULL;

}

(2)建立连接

Server端:

(Socket *m_pListenSocket=new(Socket);

if(m_pListenSocket Create(8050))

{

     if(!m_pListenSocket Listen())

{

 messageBos(“Port Error!”,”ErrorInfo”,MB_OK);

}

}

Client端:

if(!pSocket Connect(“127.0.0.1”,8050))

  {

    Delete pSocket;

    messageBox(“Connect Server Error!”,”ErrorInfo”,MB_OK);

    return NULL;

}

(3)发送和接受数据

pSocket send(Sendmsg strlen(send(msg));

ByteConunt=pSocket Receive(Revmsg,1000);

(4)删除Csocket对象

If(m_pSocket)

{

Delete pSocket;

pSoclet=NULL;

}

Else {

    messageBox(Connection is not exist!”,”ErrorInfo”,MK_OK);

}

原文来自:《基于FTP协议的WinSock程序实现》顾斌

ftp客户端ftpclient纯C语言winsock实现socket编程 /* *本程序是2009年计算机网络课程设计作品。 *本程序参考rfc959标准。能准确与遵守此标准的服务器进行信息交互。 *本人不保留任何版权。 *本程序仅供学习研究测试使用。因使用本程序所有或部分代码所产生的任何后果,本人均不负任何法律责任。 *2009年7月13日 */ #include #include #include /*system()*/ #include #pragma comment(lib,"ws2_32.lib") #define ONUM 512 #define MNUM 512 #define FNUM 512 #define pt struct host { char ip[20]; unsigned short port; }; SOCKET ts; fd_set readfds; struct timeval timeval; struct host host; char renum[4]; char ordertemp[ONUM]; char order[ONUM]; char ordercp[ONUM]; char mess[MNUM]; char file[FNUM]; char setpath[FNUM]; char setpathf[FNUM]; int i,door,r,sys,seti;/*i for;door switch;r receive num;sys system state;set set state*/ char *p;/*strtok*/ int printmess(); void input(char ordertemp[]); int ftp(); int user(); int pass(); int command(); int list(); SOCKET createDataSocket(); int set(); int retr(); int stor(); int stor() { char filename[256]; SOCKET ds; int wi; int r2,r3,r4,bsnum,brnum; FILE *fp=NULL; set(); memset(filename,'\0',256); memset(order,'\0',ONUM); for(i=5;ibsnum); }/*while*/ printf("\n"); switch(printmess()) { case 425: case 426: case 451: case 551: case 552:closesocket(ds);fclose(fp);return -1; case 250: case 226:fclose(fp);return 0; default:return 0; } }/*stor*/ int retr() { char filename[256]; unsigned long fsize,wfsize; int r2,wi; SOCKET ds; FILE *fp=NULL; memset(filename,'\0',256); memset(order,'\0',ONUM); for(i=5;i<=200&&ordercp[i]!='\0';i++)order[i-5]=ordercp[i]; strcpy(filename,setpathf); strcat(filename,"\\\\"); strcat(filename,order); ds=createDataSocket(); if(ds==-1)return -1; memset(order,'\0',ONUM); strcpy(order,"type i\r\n");/*type i 二进制 type a ASCII*/ send(ts,order,strlen(order),0); switch(printmess()) { case 421:closesocket(ds);closesocket(ts);sys=0;return 421; case 530:closesocket(ds);sys=1;return -1; case 500: case 501: case 504: case 226:closesocket(ds);return -1; case 200:break; default:closesocket(ds);return -1; } strcat(ordercp,"\r\n"); send(ts,ordercp,strlen(ordercp),0); switch(printmess()) { case 421:closesocket(ds);closesocket(ts);sys=0;return 421; case 530:closesocket(ds);sys=1;return -1; case 450: case 500: case 501: case 550:closesocket(ds);return -1; case 125: case 150:break; default:closesocket(ds);return -1; } set(); system(setpath); fp=fopen(filename,"wb"); if(!fp){printf("create file fail!\n");closesocket(ds);printmess();return -1;} wi=1;fsize=0;wfsize=0; while(wi) { memset(file,'\0',FNUM); r=recv(ds,file,FNUM,0); if(r==SOCKET_ERROR) { printf("file recv error!\n"); closesocket(ds); fclose(fp); return -1; } fsize=fsize+r; if(r==0){wi=0;break;} printf("receive %8d bytes! have received %16d bytes!\r",r,fsize); r2=fwrite(file,sizeof(char),r,fp); fflush(fp);/*这里是关键*/ wfsize=wfsize+r2; printf("write %8d bytes!have written %20d bytes!\r",r2,wfsize); }/*while*/ printf("\n"); switch(printmess()) { case 425: case 426: case 451:closesocket(ds);fclose(fp);return -1; case 250: case 226: closesocket(ds); wi=1; while(wi)if(fclose(fp)==0)wi=0;return 0; default:return 0; } }/*retr()*/ 以下代码请下载本程序。VC++6.0编译通过
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值