MFC Socket简单服务器与客户端源码

本文介绍了一个服务器端和客户端之间的交互过程,用于实现文件传输功能。服务器端使用多线程处理客户端请求,而客户端则通过命令行界面与服务器进行交互,包括认证、发送文件等操作。

服务器端代码:

#include "stdafx.h"
#include "MTServer.h"
SOCKET server;
using  namespace  std;
UINT   MTServerThread( LPVOID  pParam);
UINT   ClientThread( LPVOID  pParam);
BOOL  ParseCmd( char  *str, CString& cmd, CString& params);
BOOL  SendFile(SOCKET s, CString fname);
int  _tmain( int  argc,  TCHAR * argv[],  TCHAR * envp[])
{
     int  nRetCode = 0; 
     cout <<  "Press ESCAPE to terminate program\r\n" ;
     AfxBeginThread(MTServerThread,0);
     while (_getch()!=27);
     closesocket(server);
     WSACleanup();
     return  nRetCode;
}
UINT   MTServerThread( LPVOID  pParam)
{     
     WSADATA wsaData;
     sockaddr_in local;
     int  wsaret=WSAStartup(0x101,&wsaData);
     if (wsaret!=0)
     {
         return  0;
     }
     local.sin_family=AF_INET;
     local.sin_addr.s_addr=INADDR_ANY;
     local.sin_port=htons((u_short)20248);
     server=socket(AF_INET,SOCK_STREAM,0);
     if (server==INVALID_SOCKET)
     {
         return  0;
     }
     if (bind(server,(sockaddr*)&local, sizeof (local))!=0)
     {
         return  0;
     }
     if (listen(server,10)!=0)
     {
         return  0;
     }
     SOCKET client;
     sockaddr_in from;
     int  fromlen= sizeof (from);
     while ( true )
     {
         client=accept(server,
             ( struct  sockaddr*)&from,&fromlen);
         AfxBeginThread(ClientThread,( LPVOID )client);  
    
     return  0;
}
UINT   ClientThread( LPVOID  pParam)
{
     char  buff[512];
     CString cmd;
     CString params;
     int  n;
     int  x;
     BOOL  auth= false ;
     SOCKET client=(SOCKET)pParam;
     strcpy (buff, "#Server Ready.\r\n" );
     send(client,buff, strlen (buff),0);
     while ( true )
     {
         n=recv(client,buff,512,0);
         if (n==SOCKET_ERROR )          
             break ;
         buff[n]=0;
         if (ParseCmd(buff,cmd,params))
         {
             if (cmd== "QUIT" )
                 break ;
             if (cmd== "AUTH" )
             {
                 if (params== "passwd" )
                 {
                     auth= true ;
                     strcpy (buff, "#You are logged in.\r\n" );
                 }
                 else
                 {
                     strcpy (buff, "!Bad password.\r\n" );
                 }
                 send(client,buff, strlen (buff),0);
             }
             if (cmd== "FILE" )
             {
                 if (auth)
                 {
                     if (SendFile(client,params))
                         sprintf (buff, "#File %s sent successfully.\r\n" ,params);
                     else
                         sprintf (buff, "!File %s could not be opened.\r\n" ,params);
                     x=send(client,buff, strlen (buff),0);               
                 }
                 else
                 {
                     strcpy (buff, "!You are not logged in.\r\n" );
                     send(client,buff, strlen (buff),0);
                 }
             }
         }
         else
         {
             strcpy (buff, "!Invalid command.\r\n" );
             send(client,buff, strlen (buff),0);
         }
     }     
     closesocket(client);
     return  0;
}
BOOL  ParseCmd( char  *str, CString& cmd, CString& params)
{
     int  n;
     CString tmp=str;  
     tmp.TrimLeft();
     tmp.TrimRight();  
     if ((n=tmp.Find( ' ' ))==-1)
     {
         tmp.MakeUpper();
         if (tmp!= "QUIT" )
             return  false ;
         cmd=tmp;
         return  true ;
     }     
     cmd=tmp.Left(n);
     params=tmp.Mid(n+1);
     cmd.MakeUpper();
     if ((cmd!= "AUTH" ) && (cmd!= "FILE" ))
         return  false ;
     return  true ;
}
BOOL  SendFile(SOCKET s, CString fname)
     CFile f;
     BOOL  p=f.Open(fname,CFile::modeRead); 
     char  buff[1024];
     int  y;
     int  x;
     if (!p)
         return  false ;
     while ( true )
     {     
         y=f.Read(buff,1024);
         x=send(s,buff,y,0);   
         if (y<1024)
         {
             f.Close();
             break ;
         }         
    
     return  true ;
}


客户端代码:
 
#include "stdafx.h"
#include "MTSClient.h"
int  EndFile( char  *buff,  int  len) ;
int  NoFile( char  *buff,  int  len) ;
using  namespace  std;
int  _tmain( int  argc,  TCHAR * argv[],  TCHAR * envp[])
{
     const  char * servername= "127.0.0.1" ;
     if (argc<2)
     {
         cout <<  "Usage :- mtsclient [file1] [file2] [file3] ....\r\n" ;
         return  0;
     }
               
     WSADATA wsaData;
     struct  hostent *hp;
     unsigned  int  addr;
     struct  sockaddr_in server;
     int  wsaret=WSAStartup(0x101,&wsaData);
     if (wsaret)
         return  0;
     SOCKET conn;
     conn=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
     if (conn==INVALID_SOCKET)
         return  0;
               
     if (inet_addr(servername)==INADDR_NONE)
     {
         hp=gethostbyname(servername);
     }
     else
     {
         addr=inet_addr(servername);
         hp=gethostbyaddr(( char *)&addr, sizeof (addr),AF_INET);
     }
     if (hp==NULL)
     {
         closesocket(conn);
         return  0;
     }
     server.sin_addr.s_addr=*((unsigned  long *)hp->h_addr);
     server.sin_family=AF_INET;
     server.sin_port=htons(20248);
     if (connect(conn,( struct  sockaddr*)&server, sizeof (server)))
     {
         closesocket(conn);
         return  0; 
     }
     char  buff[512];
     int  z;
     z=recv(conn,buff,512,0);
     buff[z]=0;
               
     strcpy (buff, "auth passwd\r\n" );
     send(conn,buff, strlen (buff),0);
               
     z=recv(conn,buff,512,0);
     buff[z]=0;
               
               
     for ( int  j=1;j<argc;j++)
    
         sprintf (buff, "file %s\r\n" ,argv[j]);
         send(conn,buff, strlen (buff),0);
                   
         CFile f;
         char  *fname;
         char  fname2[256];
         if (!(fname= strrchr (argv[j], '\\' )))
             strcpy (fname2,argv[j]);
         else
             strcpy (fname2,fname+1);
         cout << fname2 <<  " has been saved.\r\n" ;
         f.Open(fname2,CFile::modeCreate | CFile::modeWrite);
         bool  first= true ;
         bool  second= false ;
         while ( true )
         {     
             z=recv(conn,buff,128,0);
             if (z==SOCKET_ERROR)
             {
                 cout <<  "\r\n\r\nsocket error socket error socket error\r\n" ;
                 break ;
            
             if (second)
             {
                 if (NoFile(buff,128)<128)
                 {
                     cout <<  "File "  << argv[j] <<  " not found on server\r\n" ;
                     break ;
                 }
                 second= false ;
             }
             if (first)
             {
                 if (NoFile(buff,128)<128)
                 {
                     cout <<  "File "  << argv[j] <<  " not found on server\r\n" ;
                     break ;
                 }
                 first= false ;
                 second= true ;
             }
                       
             int  b;
             if ((b=EndFile(buff,z))<z)
             {     
                 f.Write(buff,b);
                 cout << fname2 <<  " has been saved.\r\n" ;
                 break ;
             }
             f.Write(buff,z);
        
         f.Close();
     }
     closesocket(conn);
     WSACleanup();
     return  0;
               
}
int  EndFile( char  *buff,  int  len)
{
     int  pos=len;
     for ( int  u=0;u<(len-4);u++)
     {
         if (buff[u]== '#' )
             if (buff[u+1]== 'F' )
                 if (buff[u+2]== 'i' )
                     if (buff[u+3]== 'l' )
                         if (buff[u+4]== 'e' )
                         {
                             pos=u;
                             break ;
                         }
     }
     return  pos;
}
int  NoFile( char  *buff,  int  len)
{
     int  pos=len;
     for ( int  u=0;u<(len-4);u++)
     {
         if (buff[u]== '!' )
             if (buff[u+1]== 'F' )
                 if (buff[u+2]== 'i' )
                     if (buff[u+3]== 'l' )
                         if (buff[u+4]== 'e' )
                         {
                             pos=u;
                             break ;
                         }
     }
     return  pos;
}

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://binge518.blog.51cto.com/1554719/1222251



评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值