一个简单的在本地传输文件的网络程序

来源:互联网 发布:美股行情软件 编辑:程序博客网 时间:2024/05/21 08:49

经常在CSDN贴吧看见很多关于网络之间传输的例子(比如传输截屏文件),所以很想写一个作为学习。

此程序设定很简单,就是在本地传输。当然,要扩展到网络也很简单,改个ip就ok了。

基本思路:

双方遵循一个包头格式,根据包头确定之后的操作。

服务器代码:

#include <string>#include <io.h>#define PORT 6666struct PacketHeader{char code[10];// 指令:"EOF"=断开连接  "PIC"=接收图片char name[50];// 名字:包括后缀LONG32 size;// 大小:字节PacketHeader(){memset(code,0,sizeof(code));memset(name,0,sizeof(name));size = 0;}};// 在本地传输图片void server(){WSADATA wd;int ret = WSAStartup(MAKEWORD(2,2),&wd);if(ret != 0){cout<<"Initialize Winsock Failed! "<<GetLastError()<<endl;;return;}cout<<"WSAStartup OK"<<endl;sockaddr_in addr_serv,addr_cli;int sock_listen,sock_accept;try{sock_listen = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(sock_listen == SOCKET_ERROR){cout<<"create socket failed! "<<GetLastError()<<endl;throw 1;}cout<<"socket OK"<<endl;memset((void*)&addr_serv,0,sizeof(sockaddr));addr_serv.sin_family = AF_INET;addr_serv.sin_addr.S_un.S_addr = INADDR_ANY;addr_serv.sin_port = htons(PORT);ret = bind(sock_listen,(sockaddr*)&addr_serv,sizeof(addr_serv));if(ret != 0){cout<<"bind failed! "<<GetLastError()<<endl;throw 2;}cout<<"bind OK"<<endl;ret = listen(sock_listen,1);if(ret != 0){cout<<"listen failed! "<<GetLastError()<<endl;throw 2;}cout<<"listen OK"<<endl;int addrlen = sizeof(addr_cli);sock_accept = accept(sock_listen,(sockaddr*)&addr_cli,&addrlen);if(sock_accept == INVALID_SOCKET){cout<<"accept failed! "<<GetLastError()<<endl;throw 2;}cout<<"accept OK"<<endl;closesocket(sock_listen);//停止监听while(true){cout<<"输入:(EOF表示断开连接,文件名表示发送文件,例如sumos.txt)"<<endl;string input;cin>>input;if(input.compare("EOF") == 0){PacketHeader ph;strcpy_s(ph.code,"EOF");send(sock_accept,(const char*)&ph,sizeof(ph),0);break;}else {FILE* fp = NULL;fopen_s(&fp,input.c_str(),"rb");if(fp == NULL){cout<<"打开失败"<<endl;continue;}else{LONG32 sz = _filelength(_fileno(fp));cout<<"文件打开成功,大小:"<<sz<<" Bytes"<<endl;PacketHeader ph;strcpy_s(ph.code,"PIC");strcpy_s(ph.name,input.c_str());ph.size = sz;send(sock_accept,(const char*)&ph,sizeof(ph),0);cout<<"已发送头部信息"<<endl;int nSend = 0;char buffer[1024];while(nSend < sz){int nBytes = fread(buffer,sizeof(char),1024,fp);if(nBytes <= 0)break;send(sock_accept,buffer,nBytes,0);cout<<"已发送 "<<nBytes<<" Bytes"<<endl;nSend += nBytes;}cout<<"总计发送 "<<nSend<<" Bytes"<<endl;fclose(fp);}}}closesocket(sock_accept);}catch(int which){if(which == 2)closesocket(sock_listen);if(which == 3)closesocket(sock_accept);}WSACleanup();}

客户端代码:

#include <WinSock.h>#pragma comment(lib,"ws2_32.lib")#define IP"127.0.0.1"#define PORT6666struct PacketHeader{char code[10];// 指令:"EOF"=断开连接  "PIC"=接收图片char name[50];// 名字:包括后缀LONG32 size;// 大小:字节PacketHeader(){memset(code,0,sizeof(code));memset(name,0,sizeof(name));size = 0;}};void client() {WSADATA wd;int ret = WSAStartup(MAKEWORD(2,2),&wd);if(ret != 0){cout<<"Initialize Winsock Failed! "<<GetLastError()<<endl;;return;}cout<<"WSAStartup OK"<<endl;sockaddr_in addr_serv;int sock;try{sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(sock == SOCKET_ERROR){cout<<"create socket failed! "<<GetLastError()<<endl;throw 1;}cout<<"socket OK"<<endl;memset((void*)&addr_serv,0,sizeof(sockaddr));addr_serv.sin_family = AF_INET;addr_serv.sin_addr.S_un.S_addr = inet_addr(IP);addr_serv.sin_port = htons(PORT);ret = connect(sock,(sockaddr*)&addr_serv,sizeof(addr_serv));if(ret == SOCKET_ERROR){cout<<"connect failed! "<<GetLastError()<<endl;throw 2;}cout<<"connect OK"<<endl;char buffer[1024];while(true){int nRecv = recv(sock,buffer,1024,0);if(nRecv <= 0)continue;else if(nRecv == sizeof(PacketHeader)){PacketHeader ph;memcpy_s(&ph,sizeof(ph),buffer,nRecv);if(strcmp(ph.code,"EOF") == 0)break;else if(strcmp(ph.code,"PIC") == 0){cout<<"文件名:"<<ph.name<<",大小:"<<ph.size<<endl;FILE* fp = NULL;fopen_s(&fp,ph.name,"wb");if(fp == NULL){cout<<"创建文件失败"<<endl;break;}else{nRecv = 0;while(nRecv < ph.size){int nBytes = recv(sock,buffer,1024,0);if(nBytes <= 0)break;cout<<"已接收 "<<nBytes<<" Bytes"<<endl;fwrite(buffer,sizeof(char),nBytes,fp);nRecv += nBytes;}cout<<"共接收 "<<nRecv<<" Bytes"<<endl;fclose(fp);}}else{cout<<"头部信息错误"<<endl;break;}}else{buffer[nRecv] = '\0';cout<<buffer<<endl;}}closesocket(sock);}catch(int which){if(which == 2)closesocket(sock);}WSACleanup();}

运行截图:


原创粉丝点击