代码语言
.
CSharp
.
JS
Java
Asp.Net
C
MSSQL
PHP
Css
PLSQL
Python
Shell
EBS
ASP
Perl
ObjC
VB.Net
VBS
MYSQL
GO
Delphi
AS
DB2
Domino
Rails
ActionScript
Scala
代码分类
文件
系统
字符串
数据库
网络相关
图形/GUI
多媒体
算法
游戏
Jquery
Extjs
Android
HTML5
菜单
网页交互
WinForm
控件
企业应用
安全与加密
脚本/批处理
开放平台
其它
【
C
】
TCP文件传输工具
作者:
开源好朋友
/ 发布于
2015/5/19
/
1136
#ifndef _SOCK_BASE_H_ #define _SOCK_BASE_H_ #include <string> #define SERVER_PORT 50000 #pragma pack(push,1) class CSocket { public: CSocket(); ~CSocket(); typedef struct stFileHeader { char flag[5]; //报文头标识 int uMessageLength; //后续整个文件的完整报文长度 int uFileNameLength; //文件名的长度,暂时不考虑路径,只有文件名 }TFileHeader, *LPFileHeader; typedef struct stThreadParam { void * pParam; int sockfd; }TThreadParam, *LPThreadParam; int CreateSockServerTcp(unsigned short uBindPort = 10086, int nNum = 10); int ConnectSockClientTcp(std::string strServIP, unsigned short uBindPort = 10086); int SmallToBigEndian(unsigned char *pData, unsigned int uDataLen); int BigToSmallEndian(unsigned char *pData, unsigned int uDataLen); }; #endif 2. [文件] sockbase.cpp ~ 2KB 下载(1) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 #include "sockbase.h" #include <sys/socket.h> #include <arpa/inet.h> #include <iostream> using namespace std; CSocket::CSocket() { } CSocket::~CSocket() { } int CSocket::CreateSockServerTcp(unsigned short uBindPort, int nNum) { int sockserverfd; //创建套接字 sockserverfd = socket(AF_INET,(int)SOCK_STREAM,0); if (-1 == sockserverfd) { return sockserverfd; } //创建套接字成功,先设置套接字地址结构 sockaddr_in servaddr; servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = INADDR_ANY; servaddr.sin_port = htons(uBindPort); //绑定套接字 int nRet = bind(sockserverfd, (sockaddr *)&servaddr, static_cast<socklen_t>(sizeof (servaddr))); if (-1 == nRet) { close(sockserverfd); sockserverfd = -1; return sockserverfd; } //绑定套接字成功,现在对套接字设置监听 nRet = listen(sockserverfd, nNum); if( -1 == nRet) { close(sockserverfd); sockserverfd = -1; return sockserverfd; } return sockserverfd; } int CSocket::ConnectSockClientTcp(string strServIP, unsigned short uBindPort ) { int sockclientfd; //创建套接字 sockclientfd = socket(AF_INET,(int)SOCK_STREAM,0); if (-1 == sockclientfd) { return sockclientfd; } //创建套接字成功,先设置套接字地址结构 sockaddr_in servaddr; servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr(strServIP.c_str()); servaddr.sin_port = htons(uBindPort); int nRet = connect(sockclientfd, (sockaddr *)&servaddr, sizeof(servaddr)); if( -1 == nRet) { close(sockclientfd); sockclientfd = -1; return sockclientfd; } return sockclientfd; } int CSocket::SmallToBigEndian(unsigned char *pData, unsigned int uDataLen) { unsigned char *pStart = pData; unsigned char *pEnd = pData + uDataLen - 1; unsigned char cTmp; while(pEnd > pStart) { cTmp = *pStart; *pStart = *pEnd; *pEnd = cTmp; ++pStart; --pEnd; } return 0; } int CSocket::BigToSmallEndian(unsigned char *pData, unsigned int uDataLen) { return SmallToBigEndian(pData, uDataLen); } #ifndef _SOCK_CLIENT_H_ #define _SOCK_CLIENT_H_ #include <string> #include "sockbase.h" using namespace std; class CSockClient :public CSocket { public: CSockClient(); ~CSockClient(); int ConnectServer(string strServerIP); int SendFile(string strFile, int sockfd); }; #endif #include "sockclient.h" #include <sys/socket.h> #include <arpa/inet.h> #include <errno.h> #include <iostream> #include <fstream> const int MAXLINE = 1*1024*1024; CSockClient::CSockClient() { } CSockClient::~CSockClient() { } int CSockClient::ConnectServer(string strServerIP) { int sockfd; sockfd = ConnectSockClientTcp(strServerIP, SERVER_PORT); if (-1 == sockfd) { cout<<"客户端连接服务器失败"<<endl; return -1; } //设置套接字选项SO_SNDBUF:设置分配给套接字的数据发送缓冲区的大小。选项值类型:整数 int nRet = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char*)&MAXLINE, sizeof(unsigned int)); if (0 != nRet) { cout<<"set sock option no_linger failed !err:%s"<<strerror(errno); return -1; } return sockfd; } int CSockClient::SendFile(string strFile, int sockfd) { if (-1 == sockfd) { cout<<"SendFile函数,错误的参数"<<endl; } ifstream fstreamIn; fstreamIn.open(strFile.c_str(), ios::binary | ios::in); if (!fstreamIn) { cout<<"打开文件失败"<<endl; return -1; } string file ; unsigned int upos = 0; if (string::npos == (upos = strFile.find_last_of('/'))) { file = strFile; } else { file = strFile.substr(upos + 1); } cout<<"文件名是:"<<file<<endl; char szSendBuf[MAXLINE] = {0}; LPFileHeader pFileHeader = (LPFileHeader)szSendBuf; strcpy(pFileHeader->flag, "YRCUC"); //大小端转换 pFileHeader->uFileNameLength = file.length(); fstreamIn.seekg(0, ios::end); upos = fstreamIn.tellg(); cout<<"文件总长度是"<<upos<<endl; pFileHeader->uMessageLength = sizeof(TFileHeader) + pFileHeader->uFileNameLength + upos; cout<<"报文总长是:"<<pFileHeader->uMessageLength<<endl; SmallToBigEndian((unsigned char *)&pFileHeader->uFileNameLength, sizeof(pFileHeader->uFileNameLength)); SmallToBigEndian((unsigned char *)&pFileHeader->uMessageLength, sizeof(pFileHeader->uMessageLength)); unsigned int uOffset = 0; uOffset += sizeof(TFileHeader); memcpy( szSendBuf + uOffset, file.c_str(), file.length()); //发送文件名 uOffset += file.length(); int nRet = 0; nRet = send(sockfd, szSendBuf, uOffset, 0); if (nRet <= 0) { cout<<"send "<<uOffset << " bytes failed, msg:"<<strerror(errno); return nRet; } cout<<"发送报文长度"<<nRet<<"实际长度:"<<uOffset<<endl; fstreamIn.seekg(ios::beg); memset(szSendBuf, 0, sizeof(szSendBuf)); int uDataSet = 0; while(uDataSet < upos) //循环读取数据,发送文件 { fstreamIn.read(szSendBuf, MAXLINE - 1); cout<<"获取到的长度是:"<<fstreamIn.gcount()<<endl; nRet = send(sockfd, szSendBuf, fstreamIn.gcount(), 0); if (nRet <= 0) { cout<<"send "<<strlen(szSendBuf) << " bytes failed, msg:"<<strerror(errno); break; } uDataSet += nRet; uOffset += nRet; } cout<<"文件读取完毕,发送"<<uDataSet<<"报文总长:"<<uOffset<<"数据"<<endl; return 0; } int main(int argc, char **argv) { if (argc < 3) { cout<<"输入参数不合法,请输入[服务器ip] [--文件名称]"<<endl; return -1; } CSockClient sockclient; int sock = sockclient.ConnectServer(argv[1]); if (-1 == sock) { cout<<"连接服务器失败"<<endl; return -1; } for (int i = 2; i < argc; ++i) { sockclient.SendFile(argv[i], sock); } while (1) { sleep(1); } close(sock); cout<<"套接字关闭"<<endl; return 0; } #ifndef _SOCK_SERVER_H_ #define _SOCK_SERVER_H_ #include "sockbase.h" class CSockServer : public CSocket { public: CSockServer(); ~CSockServer(); int AcceptConnection(); static void * RecvFileThread(void * vpParam); int RecvFile(int sockfd); }; #endif 6. [文件] sockserver.cpp ~ 5KB 下载(1) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 #include "sockserver.h" #include <sys/socket.h> #include <arpa/inet.h> #include <errno.h> #include <iostream> #include <fstream> const int MAXLINE = 1*1024*1024; using namespace std; CSockServer::CSockServer() { } CSockServer::~CSockServer() { } int CSockServer::AcceptConnection() { int sockfd; int nNum = 20; sockfd = CreateSockServerTcp(SERVER_PORT, nNum); if (-1 == sockfd) { cout<<"创建服务器套接字失败"<<endl; return -1; } sockaddr_in cliaddr; socklen_t socClientLen; int connfd; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED ); pthread_t tThreadT; LPThreadParam pThreadParam = NULL; while(1) { connfd = accept(sockfd,(sockaddr *)&cliaddr,&socClientLen); if( -1 == connfd) { cout<<"连接失败"<<endl; return -1; } cout<<"客户端:"<<inet_ntoa(cliaddr.sin_addr)<<"连接服务器成功"<<endl; pThreadParam = new TThreadParam; pThreadParam->pParam = this; pThreadParam->sockfd = connfd; if (pthread_create(&tThreadT, &attr, RecvFileThread, pThreadParam)) { cout<<"create RecvFileThread failed"<<endl; return -1; } pthread_attr_destroy(&attr); } return 0; } void * CSockServer::RecvFileThread(void * vpParam) { if (NULL == vpParam) { return (void *)1; } LPThreadParam pTheadParam = (LPThreadParam)vpParam ; CSockServer * pSockServer = (CSockServer *) pTheadParam->pParam; cout<<"创建线程"<<endl; pSockServer->RecvFile(pTheadParam->sockfd); } int CSockServer::RecvFile(int sockfd) { if (-1 == sockfd) { return -1; } //设置socket超时 struct timeval timeout; timeout.tv_sec = 3; timeout.tv_usec = 0; fd_set readfds; char * szBuffer = new char[MAXLINE]; int nDataLen = 0; int nHeadLen = 0; int nFileLen = 0; LPFileHeader pFileHeader = NULL; unsigned int uOffset = 0; char szFileName[100] = {0}; ofstream fstreamOut ; int nRet = 0; //设置套接字选项SO_RCVBUF:面向接收操作,为每个套接字分别获取或设置缓冲区长度。选项值类型:整数 nRet = setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&MAXLINE, sizeof(unsigned int)); if (0 != nRet) { cout<<"set sock option no_linger failed !err:%s"<<strerror(errno); return -1; } int nFile = 0; while(1) { //使用select模式 FD_ZERO(&readfds); FD_SET(sockfd, &readfds); if(1 != select(sockfd+1, &readfds, NULL, NULL, &timeout)) //返回对应位仍然为1的fd的总数。注意啦:只有那些可读,可写以及有异常条件待处理的fd位仍然为1。否则为0哦 { // WRITELOG(LOG_ERROR, "set timeout failed"); usleep(10); continue; } //套接字已就绪,可以读取数据 if(FD_ISSET(sockfd, &readfds)) //用于测试指定的文件描述符是否在该集合中 { memset(szBuffer, 0, MAXLINE); //先窥探 nRet = recv(sockfd, szBuffer, MAXLINE, MSG_PEEK); if (nRet <= 0) { cout<<"对端关闭"<<endl; close(sockfd); return nRet; } pFileHeader = (LPFileHeader)szBuffer; if (0 != strcmp(pFileHeader->flag, "YRCUC")) //非报文头 { fstreamOut.open(szFileName, ios::app | ios::binary); if (!fstreamOut) { cout<<"打开文件:"<<szFileName<<"失败"<<endl; } if (uOffset + nRet >= nDataLen) //包含有另外个数据包的数据 { nRet = recv(sockfd, szBuffer, nDataLen - uOffset, 0); fstreamOut.write(szBuffer, nRet); cout<<"文件["<<szFileName<<"]读取完毕"<<endl; uOffset = 0; } else { nRet = recv(sockfd, szBuffer, MAXLINE, 0); fstreamOut.write(szBuffer, nRet); uOffset += nRet; } nFile += nRet; cout<<"本次收到的数据大小是:"<<nRet<<"已收到数据"<<nFile<<endl; fstreamOut.close(); } else //报文头 { cout<<"---------------------报文头"<<endl; //大端转换小端 BigToSmallEndian((unsigned char *)&pFileHeader->uFileNameLength, sizeof(pFileHeader->uFileNameLength)); BigToSmallEndian((unsigned char *)&pFileHeader->uMessageLength, sizeof(pFileHeader->uMessageLength)); nDataLen = pFileHeader->uMessageLength; nHeadLen = sizeof(TFileHeader); //报文头长度 nFileLen = pFileHeader->uFileNameLength; int nLen = nHeadLen + nFileLen; cout<<"报文头长度是"<<nHeadLen<<",文件长度是:"<<pFileHeader->uFileNameLength<<endl; memset(szBuffer, 0, MAXLINE); //读取报文头+文件名长度的数据 cout<<"read的长度是"<<nLen<<endl; nRet = recv(sockfd, szBuffer, nLen, 0); if (nRet <= 0) { cout<<"对端关闭"<<endl; close(sockfd); return nRet; } memset(szFileName, 0, sizeof(szFileName)); //文件名 memcpy(szFileName, szBuffer + nHeadLen , nFileLen); szFileName[nFileLen] = '\0'; uOffset = nLen; cout<<"文件"<<szFileName<<"的总报文长是:"<<nDataLen<<endl; } cout<<"数据读取完毕,等待下一轮读取"<<endl; } } delete [] szBuffer; return 0; } int main() { CSockServer sockserver; sockserver.AcceptConnection(); while (1) { sleep(1); } return 0; } int CSockClient::SendFile(string strFile, int sockfd) { if (-1 == sockfd) { cout<<"SendFile函数,错误的参数"<<endl; } ifstream fstreamIn; fstreamIn.open(strFile.c_str(), ios::binary | ios::in); if (!fstreamIn) { cout<<"打开文件失败"<<endl; return -1; } string file ; unsigned int upos = 0; if (string::npos == (upos = strFile.find_last_of('/'))) { file = strFile; } else { file = strFile.substr(upos + 1); } cout<<"文件名是:"<<file<<endl; char szSendBuf[MAXLINE] = {0}; LPFileHeader pFileHeader = (LPFileHeader)szSendBuf; strcpy(pFileHeader->flag, "YRCUC"); //大小端转换 pFileHeader->uFileNameLength = file.length(); fstreamIn.seekg(0, ios::end); upos = fstreamIn.tellg(); cout<<"文件总长度是"<<upos<<endl; pFileHeader->uMessageLength = sizeof(TFileHeader) + pFileHeader->uFileNameLength + upos; cout<<"报文总长是:"<<pFileHeader->uMessageLength<<endl; SmallToBigEndian((unsigned char *)&pFileHeader->uFileNameLength, sizeof(pFileHeader->uFileNameLength)); SmallToBigEndian((unsigned char *)&pFileHeader->uMessageLength, sizeof(pFileHeader->uMessageLength)); unsigned int uOffset = 0; uOffset += sizeof(TFileHeader); memcpy( szSendBuf + uOffset, file.c_str(), file.length()); //发送文件名 uOffset += file.length(); int nRet = 0; nRet = send(sockfd, szSendBuf, uOffset, 0); if (nRet <= 0) { cout<<"send "<<uOffset << " bytes failed, msg:"<<strerror(errno); return nRet; } cout<<"发送报文长度"<<nRet<<"实际长度:"<<uOffset<<endl; fstreamIn.seekg(ios::beg); memset(szSendBuf, 0, sizeof(szSendBuf)); int uDataSet = 0; while(uDataSet < upos) //循环读取数据,发送文件 { fstreamIn.read(szSendBuf, MAXLINE - 1); cout<<"获取到的长度是:"<<fstreamIn.gcount()<<endl; nRet = send(sockfd, szSendBuf, fstreamIn.gcount(), 0); if (nRet <= 0) { cout<<"send "<<strlen(szSendBuf) << " bytes failed, msg:"<<strerror(errno); break; } uDataSet += nRet; uOffset += nRet; } cout<<"文件读取完毕,发送"<<uDataSet<<"报文总长:"<<uOffset<<"数据"<<endl; return 0; }
试试其它关键字
TCP文件
传输工具
文件传输
同语言下
.
获取手机通讯录 iOS去除数字以外的所有字符
.
异步加载音乐等资源
.
交通罚单管理系统
.
freemark实现,简单的替换
.
计算斐波那契数列
.
base64解码 包括解码长度
.
图像显示
.
冒泡排序
.
输入十进制数,输出指定进制
.
链式栈
可能有用的
.
C#实现的html内容截取
.
List 切割成几份 工具类
.
SQL查询 多列合并成一行用逗号隔开
.
一行一行读取txt的内容
.
C#动态修改文件夹名称(FSO实现,不移动文件)
.
c# 移动文件或文件夹
.
c#图片添加水印
.
Java PDF转换成图片并输出给前台展示
.
网站后台修改图片尺寸代码
.
处理大图片在缩略图时的展示
开源好朋友
贡献的其它代码
(
2
)
.
下载中文名乱码
.
TCP文件传输工具
Copyright © 2004 - 2024 dezai.cn. All Rights Reserved
站长博客
粤ICP备13059550号-3