2024年3月30日发(作者:)
准备工作VC6.0添加ws2_到工程,如下图操作:
1.首先添加winsock库到工程
2.添加lib库文件
3.添加ws2_切记用空格隔开
4.点击OK即可
源代码:
FTP_Client:
#pragma comment( lib, "ws2_" )
#include
#include
#include
#include
#include
#include
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
TRAN_SUCCESS 1 //传输成功
SOCK_WSA_ERR (-1) //启动winsock库失败
SOCK_CRSOCK_ERR (-2) //创建套接字失败
SOCK_BIND_ERR (-3) //绑定端口失败
SOCK_LISTEN_ERR (-4) //监听失败
SOCK_ACCEPT_ERR (-5) //等待连接失败
SOCK_SEND_ERR (-6) //发送数据失败
SOCK_CLOSE_ERR (-7) //关闭 SOCKET失败
SOCK_RECVE_ERR (-8) //接受数据失败
SOCK_CONNECT_ERR (-10)
#define FILE_ERR (-9) //文件错误
#define Other_ERR (0) //其他不明原因
#define SVR_PORT 6000 //服务器端口
#define SEND_BUFFER_SIZE 4096 //每次发送大小
#define RECV_BUFFER_SIZE 4096 //每次发送大小
struct Fileinfo
{
char fileName[50]; //文件名
int fileBlock; //文件分块大小
int BlockNum; //文件块数量
unsigned long fileSize; //文件总大小
};
int RecevData( SOCKET s );
int Client(char* fileName);
void PrintReturn(int nRet);
int Client( char* strIP)
//int Client()
//int Client(char* fileName)
{
int nResult = 0;
//1、启动Winsock:对Winsock DLL进行初始化,协商Winsock的版本支持并分
配必要的资源。(服务器端和客户端)
WORD wVersion = MAKEWORD( 2, 0 );//wversion为winsock库的版本,高位字
节为副版本,地位字节为主版本
WSADATA wsData;
nResult = WSAStartup( wVersion, &wsData );//加载winsock库,wsData参数是
指向LPWSADATA结构的指针
if( nResult !=0 )
{
return SOCK_WSA_ERR;
}
if( LOBYTE( on ) != 2 ||
HIBYTE( on ) != 0 )
{
WSACleanup();
// return;
exit(0);
}
//2、创建套接字:(服务器端和客户端)
SOCKET s = socket( AF_INET, SOCK_STREAM, 0 );//创建套接字
if( s == INVALID_SOCKET )
{
return SOCK_CRSOCK_ERR; //错误处理
}
/*
unsigned long uladdr;
uladdr = inet_addr("127.0.0.1");
//sock=socket(AF_INET,SOCK_STREAM,0);
sockaddr_in sa;
memset(&sa,0,sizeof(sa));
_family=AF_INET;
_port=htons(5150);
_addr.S_un.S_addr=uladdr;
nResult = connect(s,(const sockaddr*)&sa,sizeof(sa));
//4、套接字的连结:将两个套接字连结起来准备通信。(客户端)
*/
/*int connect(SOCKET s, const struct sockaddr FAR * name, int namelen )
s为欲连结的已创建的套接字。
name为欲连结的socket地址。
namelen为socket地址的结构的长度。*/
unsigned long uladdr;
uladdr = inet_addr(strIP);
// uladdr = inet_addr("192.168.2.79"); //此处设定的是Server端IP地址
// uladdr = inet_addr("127.0.0.1");
sockaddr_in addr;
memset( &addr , 0x00 , sizeof( addr ));
addr. sin_family = AF_INET;
addr. sin_port = htons(SVR_PORT); //保证字节顺序
// addr. sin_addr.s_addr = htonl( uladdr );
写法很奇怪*************//
//保证字节顺序**********这种
_addr.S_un.S_addr = uladdr;
nResult = connect( s, ( sockaddr*)&addr, sizeof( sockaddr ) );
if( nResult<0)
{
return SOCK_CONNECT_ERR; //错误处理
}
/************************/
char RecvBuf[100];
recv(s,RecvBuf,100,0);
printf("%sn",RecvBuf);
// char SendFileName[100];
// send(s,fileName,strlen(fileName) + 1,0);
/************************/
//6、 套接字的数据接收:(客户端)
nResult = RecevData( s );
if(nResult<0)
{
return nResult; //错误处理
}
//7、 关闭套接字:释放所占有的资源。(服务器端和客户端)
nResult=closesocket(s);
if(nResult<0)
{
return SOCK_CLOSE_ERR; //错误处理
}
return TRAN_SUCCESS;
}
//---------------------------------------------------------------------------------
int RecevData( SOCKET s )
{
FILE* stream;
struct Fileinfo fileinfo;
int nRet = 0;
// unsigned long dataLength, cbBytesRet, cbLeftToReceive;
unsigned long dataLength, cbLeftToReceive;
BYTE* recdData = NULL;
memset( &fileinfo, 0x00, sizeof(fileinfo) );
nRet = recv( s , ( char *)&fileinfo, sizeof(fileinfo), 0 );
if( nRet == SOCKET_ERROR )
{
return SOCK_RECVE_ERR;
}
if( ( stream = fopen( me, "wb") ) == NULL)
{
return FILE_ERR;
}
// char *tt;
// nRet = send( s, ( char *)"OK" , sizeof( "OK" ),0 );
dataLength = ze;
recdData = new byte[RECV_BUFFER_SIZE];
cbLeftToReceive = dataLength;
int ii=0;
do
{
int iiGet, iiRecd;
iiGet = ( cbLeftToReceive < RECV_BUFFER_SIZE
RECV_BUFFER_SIZE ;
iiRecd = recv( s, ( char *)recdData, iiGet, 0 );
// test for errors and get out if they occurred
if ( iiRecd == SOCKET_ERROR || iiRecd == 0 )
{
return SOCK_RECVE_ERR;
}
printf("%dn",ii++);
) ? cbLeftToReceive :
fwrite( recdData, iiRecd, 1, stream ); // Write it
cbLeftToReceive -= iiRecd;
send(s, (char *)&ii,sizeof(ii),0);
}
while ( cbLeftToReceive > 0 );
return TRAN_SUCCESS;
}
void PrintReturn( int nRet)
{
switch( nRet )
{
case TRAN_SUCCESS: cout< 成功 case SOCK_WSA_ERR: cout<<"SOCK_WSA_ERR"< //传输 //启动winsock失败 case SOCK_CRSOCK_ERR: cout<<"SOCK_CRSOCK_ERR"< //创建套接字失败 case SOCK_BIND_ERR: 端口失败 cout<<"SOCK_BIND_ERR"< case SOCK_LISTEN_ERR: cout<<"SOCK_LISTEN_ERR"< 监听失败 // case SOCK_ACCEPT_ERR: //等待连接失败 cout<<"SOCK_ACCEPT_ERR"< case SOCK_SEND_ERR: 数据失败 cout<<"SOCK_SEND_ERR"< case SOCK_CLOSE_ERR: SOCKET失败 cout<<"SOCK_CLOSE_ERR"< case SOCK_RECVE_ERR: 数据失败 cout<<"SOCK_RECVE_ERR"< case SOCK_CONNECT_ERR: cout<<"SOCK_CONNECT_ERR"< case FILE_ERR: cout<<"FILE_ERR"< case Other_ERR: cout<<"Other_ERR"< default: cout<<"NO ERROR"< } } int main() { char ip[] = ""; // char filename[] = ""; cout<<"Please enter the FTPServer's IP Address:"< cin>>ip; // scanf("%s",ip); // cout<<"please enter the file you want on the FTP:"< // cin>>filename; // scanf("%s",filename); system("pause"); int nRet = Client(ip); PrintReturn( nRet ); cout<<"Recv OK"< return 0; } FTP_Server: #pragma comment( lib, "ws2_" ) #include #include #include #include #include #define TRAN_SUCCESS 1 //传输成功 #define SOCK_WSA_ERR (-1) //启动winsock失败 #define SOCK_CRSOCK_ERR (-2) //创建套接字失败 #define SOCK_BIND_ERR (-3) //绑定端口失败 #define SOCK_LISTEN_ERR (-4) //监听失败 #define SOCK_ACCEPT_ERR (-5) //等待连接失败 #define SOCK_SEND_ERR (-6) //发送数据失败 #define SOCK_CLOSE_ERR (-7) //关闭 SOCKET失败 #define SOCK_RECVE_ERR (-8) //接受数据失败 #define FILE_ERR (-9) //文件错误 #define Other_ERR (0) //其他不明原因 #define SVR_PORT 6000 //服务器端口 #define SEND_BUFFER_SIZE 4096 //每次发送大小 struct Fileinfo { char fileName[50]; //文件名 int fileBlock; //文件分块大小 int BlockNum; //文件块数量 unsigned long fileSize; //文件总大小 }; bool GetLocalIP( char caIpAddr[] ); int FileSeReturn( int nRet); int FileSend( SOCKET* s ,char* filename ); void Printize(FILE *stream); long filesize(FILE *stream) ; //---------------------------------------------------------------------------------- int ServerSend( char* FileName ) { int nResult = 0; //1、启动Winsock:对Winsock DLL进行初始化,协商Winsock的版本支持并分 配必要的资源。(服务器端和客户端) WORD wVersion = MAKEWORD( 2, 0 ); WSADATA wsData; nResult = WSAStartup( wVersion, &wsData ); if( nResult !=0 ) { return SOCK_WSA_ERR; } if( LOBYTE( on ) != 2 || HIBYTE( on ) != 0 ) { WSACleanup(); // return; exit(0); } //2、创建套接字:(服务器端和客户端) SOCKET s = socket( AF_INET, SOCK_STREAM, IPPROTO_IP );//创建套接字 if( s == INVALID_SOCKET ) { return SOCK_CRSOCK_ERR; //错误处理 } //获取本地IP地址 /* char caLocalIp[16]="127.0.0.1"; memset( caLocalIp, 0x00, sizeof( caLocalIp ) ); if( !GetLocalIP( caLocalIp ) ) { return SOCK_BIND_ERR; } */ //3、套接字的绑定:将本地地址绑定到所创建的套接字上。(服务器端和客户端) sockaddr_in sockaddr; sockaddr. sin_family =AF_INET;//告知我们正在使用IP地址家族 sockaddr. sin_port = htons(SVR_PORT); //保证字节顺序 // sockaddr. sin_addr.s_addr = inet_addr(caLocalIp);//inet_addr将一个点式IP地 址转换为32位的无符号整数 //sockaddr. sin_addr.s_addr = htonl(INADDR_ANY); _addr.S_un.S_addr = htonl(INADDR_ANY); nResult = bind( s,(SOCKADDR*)&sockaddr, sizeof( SOCKADDR ) );//将套接字和 一个特定IP地址绑定,s代表我们希望在上面等待客户机连接的那个套接字,addr为一个 普通的缓冲区,在此处实际地填充一个地址缓冲区, if( nResult==SOCKET_ERROR) { return SOCK_BIND_ERR; //错误处理 } //4、 套接字的监听:(服务器端) nResult = listen( s , 5 ); //最多5个连接 if( nResult == SOCKET_ERROR ) { return SOCK_LISTEN_ERR; //错误处理 } //5、套接字等待连接::(服务器端) sockaddr_in clientaddr; SOCKET s_c; int len; len = sizeof ( clientaddr ); //memset( cliaddr , 0x00, len); s_c = accept( s, ( SOCKADDR*)&clientaddr, &len); /*************/ char sendBuf[100]; sprintf(sendBuf,"Welcome %s to MyFTPServer",inet_ntoa(_addr)); send(s_c,sendBuf,strlen(sendBuf) + 1,0); // char recvBuf[100]; // recv(s_c,recvBuf,100,0); // printf("nThe Client request File is %sn",recvBuf); /*************/ printf( "A Client connected OKn" ); if( s_c < 0) { return SOCK_ACCEPT_ERR; //错误处理 } //6、套接字发送数据:(服务器端和客户端) nResult = FileSend( &s_c, FileName ); if( nResult < 0 ) { return nResult; //错误处理 } //7、 关闭套接字:释放所占有的资源。(服务器端和客户端) nResult = closesocket( s ); if( nResult == SOCKET_ERROR ) { return SOCK_CLOSE_ERR; //错误处理 } return TRAN_SUCCESS; } //----------------------------------------------------------------------------------- ------ //发送文件的程序 int FileSend( SOCKET* s ,char* filename ) { FILE* stream; struct Fileinfo fileinfo; int nResult; if( !( stream = fopen(filename, "rb") ) ) { return FILE_ERR; } //*******************************************组织文件基本信息准备发送 **************************************** memset( &fileinfo, 0x00, sizeof(fileinfo) ); memcpy( &me, filename, sizeof( me ) ); ock = SEND_BUFFER_SIZE; long size = filesize( stream ); if(size <= SEND_BUFFER_SIZE) um = 1; else um = size / SEND_BUFFER_SIZE + 1; ze = filesize( stream ); unsigned int infolen = sizeof( fileinfo ); do { unsigned int len = sizeof( fileinfo ); nResult = send( *s, (char *)&fileinfo , len , 0 ); printf("Send Fileinfo OKn"); if ( nResult == SOCKET_ERROR ) { return SOCKET_ERROR; } infolen -= nResult; }while( infolen > 0); //发送文件基本信息 printf( "Now OK,Sended File Datan" ); //发送文件 BYTE sendData[SEND_BUFFER_SIZE] ; memset( sendData ,0x00 , SEND_BUFFER_SIZE ); //sendData = new BYTE[SEND_BUFFER_SIZE]; //每次发送指定大小文件包 int allSendSIZE = filesize( stream ); //要发送文件的整个长度 int NUM = um - 1; int endNum = size % SEND_BUFFER_SIZE; int ii = 1; int jj=1; do { unsigned long sendThisTime, doneSoFar, buffOffset; buffOffset = 0; while( !feof( stream ) ) { if( ii <= NUM) { memset( sendData ,0x00 , SEND_BUFFER_SIZE ); fread( sendData, SEND_BUFFER_SIZE, 1, stream); } else { memset( sendData ,0x00 , SEND_BUFFER_SIZE ); fread( sendData, endNum, 1, stream); } if( allSendSIZE < SEND_BUFFER_SIZE ) sendThisTime = endNum; else sendThisTime = SEND_BUFFER_SIZE; do { doneSoFar = send( *s, (char *)sendData, sendThisTime , 0 ); // test for errors and get out if they occurred if ( doneSoFar == SOCKET_ERROR ) { return SOCKET_ERROR; } buffOffset += doneSoFar; sendThisTime -= doneSoFar; allSendSIZE -= doneSoFar; } while ( sendThisTime > 0 ); recv( *s, ( char *)&ii, sizeof(ii), 0 ); printf("%dn",jj++); } } while ( allSendSIZE > 0 ); // delete[] sendData; fclose( stream ); return TRAN_SUCCESS; } // 获得本机IP地址 bool GetLocalIP( char caIpAddr[] ) { char caLocalIp[ 16 ]; char caHostName[ 100 ]; int iRtn; // unsigned long ulAddrInfo; struct hostent s_HostEnt, *pHostEnt; struct in_addr s_IpAddr; WORD wVerReq; WSADATA wsaData; wVerReq = MAKEWORD( 2, 0 ); iRtn = WSAStartup( wVerReq, &wsaData ); if( iRtn != 0 ) { return false; } if( LOBYTE( on ) != 2 || HIBYTE( on ) != 0 ) { WSACleanup(); return false; } memset( caHostName, 0x00, sizeof(caHostName) ); if( gethostname( caHostName, sizeof(caHostName) ) != 0 ) { WSACleanup(); return false; } pHostEnt = &s_HostEnt; pHostEnt = gethostbyname( caHostName ); if( pHostEnt == NULL ) { WSACleanup(); return false; } memcpy( &s_IpAddr, pHostEnt->h_addr_list[0], sizeof(struct in_addr) ); memset( caLocalIp, 0x00, sizeof(caLocalIp) ); strncpy( caLocalIp, inet_ntoa(s_IpAddr), sizeof( caLocalIp ) - 1 ); strncpy( caIpAddr, caLocalIp, sizeof( caLocalIp ) - 1 ); WSACleanup(); return true; } void PrintReturn( int nRet) { switch( nRet ) { case TRAN_SUCCESS: cout< 成功 case SOCK_WSA_ERR: cout<<"SOCK_WSA_ERR"< //启动winsock失败 //传输 case SOCK_CRSOCK_ERR: cout<<"SOCK_CRSOCK_ERR"< //创建套接字失败 case SOCK_BIND_ERR: 端口失败 cout<<"SOCK_BIND_ERR"< case SOCK_LISTEN_ERR: cout<<"SOCK_LISTEN_ERR"< 监听失败 // case SOCK_ACCEPT_ERR: //等待连接失败 cout<<"SOCK_ACCEPT_ERR"< case SOCK_SEND_ERR: 数据失败 cout<<"SOCK_SEND_ERR"< case SOCK_CLOSE_ERR: SOCKET失败 cout<<"SOCK_CLOSE_ERR"< case SOCK_RECVE_ERR: 数据失败 cout<<"SOCK_RECVE_ERR"< //case SOCK_CONNECT_ERR: cout<<"SOCK_CONNECT_ERR"< case FILE_ERR: cout<<"FILE_ERR"< case Other_ERR: cout<<"Other_ERR"< default: cout<<"NO ERROR"< } } long filesize(FILE *stream) { long curpos, length; curpos = ftell(stream); fseek(stream, 0L, SEEK_END); length = ftell(stream); fseek(stream, curpos, SEEK_SET); return length; } int main() { char filename[256]; memset( filename, 0x00, sizeof( filename ) ); //strncpy()可以将一字符串的一部分拷贝到另一字符串中 strncpy( filename, "", sizeof( filename) ); int nRet = ServerSend( filename); PrintReturn( nRet ); cout<<"Server OK"< return 0; }


发布评论