一个简单的在本地传输文件的网络程序
2012-11-16 13:48
477 查看
经常在CSDN贴吧看见很多关于网络之间传输的例子(比如传输截屏文件),所以很想写一个作为学习。
此程序设定很简单,就是在本地传输。当然,要扩展到网络也很简单,改个ip就ok了。
基本思路:
双方遵循一个包头格式,根据包头确定之后的操作。
服务器代码:
客户端代码:
运行截图:
此程序设定很简单,就是在本地传输。当然,要扩展到网络也很简单,改个ip就ok了。
基本思路:
双方遵循一个包头格式,根据包头确定之后的操作。
服务器代码:
#include <string> #include <io.h> #define PORT 6666 struct 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 PORT 6666 struct 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(); }
运行截图:
相关文章推荐
- 一个简单的点对点文件传输程序
- python实现类似ftp传输文件的网络程序示例
- 编写一个程序,一行行地读取输入行,直至到达文件尾。算出每行输入行的长度,然后把最长的那行打印出来。为了简单起见,你可以假定所有的输入行均不超过1000个字符
- 网络编程,一个ACSII文件的传输
- 一个简单的客户端和服务端网络连接程序
- 使用一个简单的python脚本将一个本地文件以码流的形式,通过UDP协议发送到对端:
- 一个简单的网络爬虫程序
- 一个简单的linux下网络程序实例-网络编程入门 收藏
- 一个简单的PHP文件上传示例程序
- Django 一个简单的图书管理程序(六 添加CSV文件导入导出操作)
- 一个简单的std 读写简单数据的文件程序
- 实战Registry和RegistryKey类,一个简单的可疑文件扫描程序
- 网络编程与多线程的应用--基于socket udp编写一个简单聊天程序
- 【C语言】没事可以试试这个小程序,使用文件操作,模拟实现一个简单的文件拷贝工具!
- WinSock实现多线程网络文件传输程序(二)(MFC+WinSock 附源代码)
- C++程序与Java程序网络传输文件测试
- 用Python实现一个简单的文件传输协议
- ASP网站数据采集程序制作:一个采集入库生成本地文件的几个FUCTION(可用来生成HTML静态网页)
- 【Java】Swing+IO流实现一个简单的文件加密程序(较完整版)
- 一个简单的Linux内核代码整合到一个文件的Java程序