C++ Socket发送文件服务端代码
来源:互联网 发布:手机淘宝晒图怎么删除 编辑:程序博客网 时间:2024/06/11 19:16
/*
**服务端代码头文件
*/
pragma comment(lib, “WS2_32”)
include
include
//#include
include
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
/*
**服务端代码源文件
*/
include “SocketTransfer.h”
char g_szNewFileName[MAXFILEDIRLENGTH];
char g_szBuff[MAX_PACKET_SIZE + 1];
long g_lLength;
char* g_pBuff = NULL;
// 初始化socket库
bool InitSocket();
// 关闭socket库
bool CloseSocket();
// 解析消息进行相应的处理
bool ProcessMsg(SOCKET sClient);
// 监听Client的消息
void ListenToClient();
// 打开文件
bool OpenFile(CCSDef::TMSG_HEADER* pMsgHeader, SOCKET sClient);
// 传送文件
bool SendFile(SOCKET sClient);
// 读取文件进入缓冲区
bool ReadFile(SOCKET sClient);
int main()
{
InitSocket();
ListenToClient();
CloseSocket();
return 0;
}
void ListenToClient()
{
// 创建socket套接字
SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (SOCKET_ERROR == sListen)
{
printf(“Init Socket Error!\n”);
return;
}
// 绑定socket到一个本地地址sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT);sin.sin_addr.S_un.S_addr = INADDR_ANY;if (::bind(sListen, (LPSOCKADDR)&sin, sizeof(sockaddr_in)) == SOCKET_ERROR){ printf("Bind Error!\n"); return;}// 设置socket进入监听状态if (::listen(sListen, 10) == SOCKET_ERROR){ printf("Listen Error!\n"); return;}printf("Listening To Client...\n");// 循环接收client端的连接请求sockaddr_in ClientAddr;int nAddrLen = sizeof(sockaddr_in);SOCKET sClient;while (INVALID_SOCKET == (sClient = ::accept(sListen, (sockaddr*)&ClientAddr, &nAddrLen))){}while (true == ProcessMsg(sClient)){}// 关闭同客户端的连接::closesocket(sClient);::closesocket(sListen);
}
bool InitSocket()
{
// 初始化socket dll
WSADATA wsaData;
WORD socketVersion = MAKEWORD(2, 2);
if (::WSAStartup(socketVersion, &wsaData) != 0)
{
printf(“Init socket dll error\n”);
return false;
}
return true;
}
bool CloseSocket()
{
// 释放winsock库
::WSACleanup();
if (NULL != g_pBuff){ delete [] g_pBuff; g_pBuff = NULL;}return true;
}
bool ProcessMsg(SOCKET sClient)
{
int nRecv = ::recv(sClient, g_szBuff, MAX_PACKET_SIZE + 1, 0);
if (nRecv > 0)
{
g_szBuff[nRecv] = ‘\0’;
}
// 解析命令CCSDef::TMSG_HEADER* pMsgHeader = (CCSDef::TMSG_HEADER*)g_szBuff;switch (pMsgHeader->cMsgID){case MSG_FILENAME: // 文件名 { OpenFile(pMsgHeader, sClient); } break;case MSG_CLIENT_READY: // 客户端准备好了,开始传送文件 { SendFile(sClient); } break;case MSG_SENDFILESUCCESS: // 传送文件成功 { printf("Send File Success!\n"); return false; } break;case MSG_FILEALREADYEXIT_ERROR: // 要保存的文件已经存在了 { printf("The file reay to send already exit!\n"); return false; } break;}return true;
}
bool ReadFile(SOCKET sClient)
{
if (NULL != g_pBuff)
{
return true;
}
// 打开文件FILE *pFile;if (NULL == (pFile = fopen(g_szNewFileName, "rb"))) // 打开文件失败{ printf("Cannot find the file, request the client input file name again\n"); CCSDef::TMSG_ERROR_MSG tMsgErrorMsg(MSG_OPENFILE_ERROR); ::send(sClient, (char*)(&tMsgErrorMsg), sizeof(CCSDef::TMSG_ERROR_MSG), 0); return false;}// 把文件的长度传回到client去fseek(pFile, 0, SEEK_END);g_lLength = ftell(pFile);printf("File Length = %d\n", g_lLength);CCSDef::TMSG_FILELENGTH tMsgFileLength(g_lLength);::send(sClient, (char*)(&tMsgFileLength), sizeof(CCSDef::TMSG_FILELENGTH), 0);// 处理文件全路径名,把文件名分解出来char szDrive[_MAX_DRIVE], szDir[_MAX_DIR], szFname[_MAX_FNAME], szExt[_MAX_EXT];_splitpath(g_szNewFileName, szDrive, szDir, szFname, szExt);strcat(szFname,szExt);CCSDef::TMSG_FILENAME tMsgFileName;strcpy(tMsgFileName.szFileName, szFname);printf("Send File Name: %s\n", tMsgFileName.szFileName);::send(sClient, (char*)(&tMsgFileName), sizeof(CCSDef::TMSG_FILENAME), 0);// 分配缓冲区读取文件内容g_pBuff = new char[g_lLength + 1];if (NULL == g_pBuff){ return false;}fseek(pFile, 0, SEEK_SET);fread(g_pBuff, sizeof(char), g_lLength, pFile);g_pBuff[g_lLength] = '\0';fclose(pFile);return true;
}
// 打开文件
bool OpenFile(CCSDef::TMSG_HEADER* pMsgHeader, SOCKET sClient)
{
CCSDef::TMSG_FILENAME* pRequestFilenameMsg = (CCSDef::TMSG_FILENAME*)pMsgHeader;
// 对文件路径名进行一些处理char *p1, *p2;for (p1 = pRequestFilenameMsg->szFileName, p2 = g_szNewFileName; '\0' != *p1; ++p1, ++p2){ if ('\n' != *p1) { *p2 = *p1; } if ('\\' == *p2) { *(++p2) = '\\'; }}*p2 = '\0';ReadFile(sClient);return true;
}
// 传送文件
bool SendFile(SOCKET sClient)
{
if (NULL == g_pBuff)
{
ReadFile(sClient);
}
int nPacketBufferSize = MAX_PACKET_SIZE - 2 * sizeof(int); // 每个数据包存放文件的buffer大小// 如果文件的长度大于每个数据包所能传送的buffer长度那么就分块传送for (int i = 0; i < g_lLength; i += nPacketBufferSize){ CCSDef::TMSG_FILE tMsgFile; tMsgFile.tFile.nStart = i; if (i + nPacketBufferSize + 1> g_lLength) { tMsgFile.tFile.nSize = g_lLength - i; } else { tMsgFile.tFile.nSize = nPacketBufferSize; } //printf("start = %d, size = %d\n", tMsgFile.tFile.nStart, tMsgFile.tFile.nSize); memcpy(tMsgFile.tFile.szBuff, g_pBuff + tMsgFile.tFile.nStart, tMsgFile.tFile.nSize); ::send(sClient, (char*)(&tMsgFile), sizeof(CCSDef::TMSG_FILE), 0); Sleep(0.5);}delete [] g_pBuff;g_pBuff = NULL;return true;
}
- C++ Socket发送文件服务端代码
- socket编程--客户端发送文件至服务端
- socket C 客户端发送数据到服务端,操作mysql数据库
- C++ Socket发送文件客户端代码
- Socket 异步 长连接 多点 服务端代码(C#)
- C语言socket服务端和客户端代码 /缓冲区/阻塞
- socket简单应用服务端代码(原创)tcp c/s
- c语言实现socket服务端/客户端通过tcp传送文件
- Java Socket编程之多线程实现C/S一对多(服务端无法发送数据)
- 安卓使用Socket发送中文,C语言服务端接收乱码问题解决方案
- Socket tcp服务端 代码示例
- php socket 服务端实现代码
- C# Socket TCP 编程,客户端与服务端连接,发送字符串,文件
- C# Socket TCP 编程,客户端与服务端连接,发送字符串,文件
- Socket向服务端发送消息工具类
- Socket向服务端发送消息工具类
- Java给服务端发送文件
- Java实现Socket发送和接收文件的代码
- Jquery学习笔记一
- 读《分布式数据库架构及企业实践》---笔记二
- Android 自定义ViewGroup 实战篇 -> 实现FlowLayout
- 23种设计模式之备忘录模式
- CSS层级总结
- C++ Socket发送文件服务端代码
- servlet过滤器
- 外星人的供给站
- 用Android studio依赖Library,gradle报错问题
- I2C子系统分析
- 生成式文本摘要分析实践
- c++中回调函数封装成抽象类
- Android Studio Cannot Load Settings from file 错误
- spring 定时任务的 执行时间设置规则【老记不住】