【转】DOS下文件传输---初识TCP网络编程改版
更新版說明:
1.在以前基礎上,添加了錯誤提示,方便查詢---使用SOCKET_ERROR檢測
2.在以前基礎上,添加了文件傳輸模塊--------使用CreateFile中ReadFile與WriteFile
3.修改完成后,使用MessageBox彈出窗口提示--確保用戶的每一步操作都正常完成,且配備提示
4.修改變量名,更標準化--------------------如s1改成sServer(小s代表socket,大S表示服務端)等
5.增強了注釋部分,使程序通俗易懂
6.完整的封裝性---------------------------使用#pragma comment(lib,"Ws2_32.lib"),復制過去不用在工程里設置鏈接庫
7.防止內存泄漏---------------------------只要發生錯誤,或完成任務,都必須馬上清理內存,釋放資源
------------代碼部分分2部分:1.服務端代碼 2.客戶端代碼----------------------
-----------------------------------1.服務端代碼--------------------------------------
#include<Winsock2.h>//WSAStartup等需要包含的頭文件
#include <windows.h>//CreateFile等需要包含的頭文件---注意第1行與第2行包含的順序---詳見備注1
#include <stdio.h>
#include<iostream>
using namespace std;
#pragma comment(lib,"Ws2_32.lib")
void main()
{
/第1步:初始化Windsock部分/
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );//注:配套的析構函數WSACleanup
if ( err != 0 ) {
?? /* Tell the user that we could not find a usable */
?? /* WinSock DLL.????????????????????????????????? */
?? return;
}
/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater??? */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we????? */
/* requested.??????????????????????????????????????? */
if ( LOBYTE( wsaData.wVersion ) != 2 ||
??????? HIBYTE( wsaData.wVersion ) != 2 ) {
?? /* Tell the user that we could not find a usable */
?? /* WinSock DLL.????????????????????????????????? */
?? WSACleanup( );?????????????????????????????????? //WSAStartup配套的析構函數WSACleanup
?? return;
}
/* The WinSock DLL is acceptable. Proceed. */
///第2步:創建套接字socket部分/
SOCKET sServer=socket(AF_INET,SOCK_STREAM,0); //配套的析構函數closesocket(socket);
if(sServer==INVALID_SOCKET){cout<<"創建套接字錯誤!"<<endl;closesocket(sServer);WSACleanup();}//或SOCKET_ERROR
///第3步:綁定套接字bind部分///
SOCKADDR_IN sbind;
sbind.sin_family=AF_INET;
sbind.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
sbind.sin_port=htons(6000);
if(SOCKET_ERROR==bind(sServer,(SOCKADDR*)&sbind,sizeof(SOCKADDR)))
?? {cout<<"綁定套接字錯誤!"<<endl;closesocket(sServer);WSACleanup();}
///第4步:監聽套接字部分??
if(SOCKET_ERROR==listen(sServer,10)){cout<<"監聽套接字錯誤!"<<endl;closesocket(sServer);WSACleanup();}
///第5步:接收客戶端部分
SOCKET sAccept=SOCKET_ERROR;SOCKADDR_IN addr_accept;int len=sizeof(SOCKADDR);cout<<"接收客戶端套接字開始:";
while(1)
{
?? while(sAccept==SOCKET_ERROR)
?? {
??? sAccept=accept(sServer,(SOCKADDR*)&addr_accept,&len);
?? }
?? break;
}
sServer=sAccept;cout<<"接收客戶端套接字,成功!"<<endl;
///第6步:發送文件部分//
HANDLE hFile=CreateFile("C:\\1.jpg",GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
char sendbuf[1024];DWORD dwRead;BOOL nReadFile;
while(1)
{
///ReadFile部分/
?? nReadFile=ReadFile(hFile,sendbuf,1024,&dwRead,0);
?? if(nReadFile==0)
??? {cout<<"ReadFile讀取文件時錯誤!"<<endl;CloseHandle(hFile);closesocket(sServer);WSACleanup();break;}
?? else if(dwRead==0)
?? {
??? MessageBox(0,"成功發送文件到客戶端!等待客戶接受完后退出","MB_OK",0);
??? CloseHandle(hFile);//千萬別加closesocket(sServer);WSACleanup();因為send還沒有用呢
??? break;
?? }
///send部分/
?? if(SOCKET_ERROR==send(sServer,sendbuf,1024,0))
??? {cout<<"ReadFile讀取文件時錯誤!"<<endl;CloseHandle(hFile);closesocket(sServer);WSACleanup();}??
}
}
-----------------------------------2.客戶端代碼--------------------------------------
#include<Winsock2.h>
#include <windows.h>
#include <stdio.h>
#include<iostream>
using namespace std;
#pragma comment(lib,"Ws2_32.lib")
void main()
{
/第1步:初始化Windsock部分/
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
?? /* Tell the user that we could not find a usable */
?? /* WinSock DLL.????????????????????????????????? */
?? return;
}
/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater??? */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we????? */
/* requested.??????????????????????????????????????? */
if ( LOBYTE( wsaData.wVersion ) != 2 ||
??????? HIBYTE( wsaData.wVersion ) != 2 ) {
?? /* Tell the user that we could not find a usable */
?? /* WinSock DLL.????????????????????????????????? */
?? WSACleanup( );
?? return;
}
/* The WinSock DLL is acceptable. Proceed. */
///第2步:創建套接字socket部分/
SOCKET sClient=socket(AF_INET,SOCK_STREAM,0); //配套的析構函數closesocket(socket);
if(sClient==INVALID_SOCKET){cout<<"創建套接字錯誤!"<<endl;closesocket(sClient);WSACleanup();}//或SOCKET_ERROR
///第3步:連接服務端部分///
SOCKADDR_IN addr_conect;
addr_conect.sin_family=AF_INET;
addr_conect.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addr_conect.sin_port=htons(6000);
if(SOCKET_ERROR==connect(sClient,(SOCKADDR*)&addr_conect,sizeof(SOCKADDR)))
?? {cout<<"連接服務端錯誤!"<<endl;closesocket(sClient);WSACleanup();}
//第4步:接收文件部分//
HANDLE hFile=CreateFile("D:\\1.jpg",GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
char recvbuf[1024];DWORD dwRecv;BOOL bWriteFile;
while(1)
{
recv部分//
?? if(SOCKET_ERROR==recv(sClient,recvbuf,1024,0))???
?? {cout<<"recv接受完成!"<<endl;CloseHandle(hFile);closesocket(sClient);WSACleanup();break;}??
?? //注:此SOCKET_ERROR返回2個信息:1.創建未成功時,返回的錯誤,2.消息發完后,返回的錯誤值...切記注意判斷
///WriteFile部分//
?? bWriteFile=WriteFile(hFile,recvbuf,1024,&dwRecv,0);
?? if(bWriteFile==0)
?? {cout<<"WriteFile寫入文件錯誤!"<<endl;CloseHandle(hFile);closesocket(sClient);WSACleanup();break;}
}
MessageBox(0,"寫入文件成功!現在退出","MB_OK",0);
}
備注1:注意#include<Winsock2.h>(在前)與#include <windows.h>(在后)包含順序,因為window.h默認(未申明)包含是1版,所以引起沖突
備注2:接受后的文件,比原文件多了1字節.比如原有是109KB,發送過來后是110KB
客戶端備注1:
之前服務端,有寫過,但是這是客戶端,無須寫.如果是雙向的,也就是即當服務也當客戶端,那就可能要寫了
if(dwRecv==0)
{
MessageBox(0,"寫入文件成功!現在退出","MB_OK",0);
CloseHandle(hFile);closesocket(sClient);WSACleanup();break;
}
客戶端備注2:
為什么接受過來的東西,有那個文件,但是里面卻什么也沒有且文件大小0?
注意CreatFile中的CREATE_ALWAYS,MSDN中介紹如果沒有文件,新建一個.如果有文件,則清除現有文件信息,并將值賦給它
---------
附注1:本例源代碼已保存至郵箱,即取即用
轉載于:https://www.cnblogs.com/findeasy/archive/2012/05/16/4053175.html
總結
以上是生活随笔為你收集整理的【转】DOS下文件传输---初识TCP网络编程改版的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FactoryBean
- 下一篇: 昨天,我的大学学习[2]