当前位置:编程学习 > C/C++ >>

使用TCP协议实现文件传输

使用TCP协议实现文件传输。程序会分为服务器端和客户端,首先运行服务器端,监听来自客户端的连接,客户端运行后会通过程序内的服务器端IP地址,向服务器发送连接请求。双方建立请求之后,客户端将所需文件的文件名和绝对路径传输给服务器,如果服务器找到此文件,则将此文件传输给客户端,然后断开连接。
 
具体算法描述如下:
 
【1】服务器端:
 
1、初始化socket服务
 
2、监听连接请求并做相应的处理
 
2.1创建监听套接字
 
2.2监听套接口
 
2.3接受套接字的连接
 
2.4接收客户端传来的数据
 
case 文件绝对路径:
 
按照路径找到文件,并打开。提取本地文件名,发回给客户端
 
发送文件总长度给客户端
 
case 已准备接收文件完毕
 
if 发送缓冲区为空
 
读取文件,写入缓冲区
 
将文件流分成大小相同的组(最后一组可能会小一点),顺次发送给客户端
 
将缓冲区清空
 
case 文件成功传送
 
打印消息,退出
 
case 文件已存在
 
打印消息,退出
 
2.5关闭同客户端的连接
 
3、释放socket服务
 
【2】客户端:
 
1、初始化socket,winsock服务
 
2、连接服务器,进行数据的传输
 
2.1初始化,创建套接字
 
2.2通过IP地址,向服务器发送连接请求,建立连接
 
2.3主动发送所求文件绝对路径
 
2.4接受服务器端数据并做相应处理
 
case 打开文件错误:
 
重新发送文件绝对路径至服务器,请求重发
 
case 文件长度:
 
打印消息
 
case 文件名:
 
if 文件已经存在
 
发送“文件已经存在”
 
else
 
分配缓冲区,并向服务器发送“Ready”消息
 
case 文件流:
 
为已接收文件名创建文件
 
打开文件,将文件流数据写入文件,直至接收所有分组数据
 
发送“成功接收“消息
 
3、关闭套接字
 
释放服务
 
源程序:
 
【1】服务器端:
 
头文件:
 
[cpp]  
/*server.h*/  
#pragma comment(lib, "WS2_32")  
#include <WinSock2.h>  
#include <iostream>  
#include <assert.h>  
#include<Windows.h>  
#ifndef COMMONDEF_H  
#define COMMONDEF_H  
#define MAX_PACKET_SIZE   10240    // 数据包的最大长度,单位是sizeof(char)  
#define MAXFILEDIRLENGTH 256     // 存放文件路径的最大长度  
#define PORT     4096    // 端口号  
//#define SERVER_IP    "127.0.0.1" // server端的IP地址  
// 各种消息的宏定义  
#define INVALID_MSG      -1   // 无效的消息标识  
#define MSG_FILENAME     1   // 文件的名称  
#define MSG_FILELENGTH     2   // 传送文件的长度  
#define MSG_CLIENT_READY    3   // 客户端准备接收文件  
#define MSG_FILE      4   // 传送文件  
#define MSG_SENDFILESUCCESS    5   // 传送文件成功  
#define MSG_OPENFILE_ERROR    10   // 打开文件失败,可能是文件路径错误找不到文件等原因  
#define MSG_FILEALREADYEXIT_ERROR 11   // 要保存的文件已经存在了  
class CCSDef  
{  
public:  
#pragma pack(1)      // 使结构体的数据按照1字节来对齐,省空间  
// 消息头  
struct TMSG_HEADER  
{  
   char    cMsgID;    // 消息标识  
   TMSG_HEADER(char MsgID = INVALID_MSG)  
    : cMsgID(MsgID)  
   {  
   }  
};  
// 请求传送的文件名  
// 客户端传给服务器端的是全路径名称  
// 服务器传回给客户端的是文件名  
struct TMSG_FILENAME : public TMSG_HEADER  
{  
   char szFileName[256];   // 保存文件名的字符数组  
   TMSG_FILENAME()  
    : TMSG_HEADER(MSG_FILENAME)  
   {  
   }  
};  
// 传送文件长度  
struct TMSG_FILELENGTH : public TMSG_HEADER  
{  
   long lLength;  
   TMSG_FILELENGTH(long length)  
    : TMSG_HEADER(MSG_FILELENGTH), lLength(length)   
   {  
   }  
};  
// Client端已经准备好了,要求Server端开始传送文件  
struct TMSG_CLIENT_READY : public TMSG_HEADER  
{  
   TMSG_CLIENT_READY()  
    : TMSG_HEADER(MSG_CLIENT_READY)  
   {  
   }  
};  
// 传送文件  
struct TMSG_FILE : public TMSG_HEADER  
{  
   union     // 采用union保证了数据包的大小不大于MAX_PACKET_SIZE * sizeof(char)  
   {  
    char szBuff[MAX_PACKET_SIZE];  
    struct  
    {  
     int nStart;  
     int nSize;  
     char szBuff[MAX_PACKET_SIZE - 2 * sizeof(int)];  
    }tFile;  
   };  
   TMSG_FILE()  
    : TMSG_HEADER(MSG_FILE)  
   {  
   }  
};  
// 传送文件成功  
struct TMSG_SENDFILESUCCESS : public TMSG_HEADER  
{  
   TMSG_SENDFILESUCCESS()  
    : TMSG_HEADER(MSG_SENDFILESUCCESS)  
   {  
   }  
};  
// 传送出错信息,包括:  
// MSG_OPENFILE_ERROR:打开文件失败  
// MSG_FILEALREADYEXIT_ERROR:要保存的文件已经存在了  
struct TMSG_ERROR_MSG : public TMSG_HEADER  
{  
   TMSG_ERROR_MSG(char cErrorMsg)  
    : TMSG_HEADER(cErrorMsg)  
   {  
   }  
};  
#pragma pack()  
};  
#endif  
 
cpp文件:
[cpp]  
/*Server.cpp*/  
#include"Server.h"  
char g_szNewFileName[MAXFILEDIRLENGTH];  
char g_szBuff[MAX_PACKET_SIZE + 1];  
long g_lLength;  
char* g_
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,