📄 test.cpp
字号:
#include "stdafx.h"
#include "test.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CWinApp theApp;
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[])
{
cout << "按下ESC车退出程序\r\n";
AfxBeginThread(MTServerThread,0);//开启一个MTserver的线程,参数为0
while(_getch()!=27);
//关闭server
closesocket(server);
//将其从Windows Sockets的实现中注销
WSACleanup();
return 0;
}
UINT MTServerThread(LPVOID pParam)
{
WSADATA wsaData;
sockaddr_in local;
//指定加载的Winsock库的版本
int wsaret=WSAStartup(0x101,&wsaData);
//调用成功则函数返回0
//调用失败,程序退出
if(wsaret!=0)
{
return 0;
}
local.sin_family=AF_INET;
local.sin_addr.s_addr=INADDR_ANY;//使用自己的ip
local.sin_port=htons((u_short)22222);
//创建我们的socket套接字
server=socket(AF_INET,SOCK_STREAM,0);
//如果socket()函数调用失败,退出
if(server==INVALID_SOCKET)
{
return 0;
}
//建立socket的本地关联
if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
{
return 0;
}
//进入监听状态
//指定backlog值为10
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];
char temp;
CString cmd;
CString params;
int n;
int x;
BOOL key=false;
SOCKET client=(SOCKET)pParam;
//把"#服务器就绪,请输入指令"放入缓存中
strcpy(buff,"#服务器就绪,请输入指令.\r\n");
//在客户端显示出来
send(client,buff,strlen(buff),0);
//进入死循环
while(true)
{
int i = 1;
//读取用户输入的字符串以回车结束,并把他们放到缓存中去
//
n=recv(client,buff,512,0);
if(buff[0]=='-')
{
while(buff[i-1]!='\n')
{
n=recv(client,buff+i,1,0);
i++;
}
buff[i]='\0';
int j=1;
while(j<i)
{
temp=buff[j];
buff[j-1]=temp;
j=j+1;
}
}
else{
if(n==SOCKET_ERROR )
break;
buff[n]='\0';
}
//解析命令代码是否成功
if(ParseCmd(buff,cmd,params))
{
//如果命令代码是"QUIT",则退出
if(cmd=="QUIT")
break;
//命令是否是"KEY"
if(cmd=="KEY")
{
//如果是,那空格后的参数是否是"passwd"
if(params=="passwd")
{
//如果是
key=true;
//把提示信息放入缓存.
strcpy(buff,"#密码正确,您已经登录.\r\n");
}
else
{
strcpy(buff,"!密码错误!\r\n");
}
//把以上信息在客户端显示出来.
send(client,buff,strlen(buff),0);
}
if(cmd=="FILE")
{
//如果登录
if(key)
{
//文件传输
if(SendFile(client,params))
sprintf(buff,"#File %s 成功打开.\r\n",params);
else
sprintf(buff,"!File %s 打开失败.\r\n",params);
x=send(client,buff,strlen(buff),0);
}
else
{
strcpy(buff,"!对不起,你没有登录,请输入密码.\r\n");
send(client,buff,strlen(buff),0);
}
}
}
else
{
//输入指令有误
strcpy(buff,"!你输入的指令有误.\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;
//去掉指令头尾的空格,回车或tab.
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!="KEY") && (cmd!="FILE"))
return false;
return true;
}
//文件传输
BOOL SendFile(SOCKET s, CString fname)
{
CFile f;
CFile cf;
//打开文件,属性为只读
BOOL p=f.Open(fname,CFile::modeRead);
char buff[1024];
int y;
int x;
int z;
if(!p)
return false;
while(true)
{
//读取1024个字
y=f.Read(buff,1024);
//发送到缓冲区
x=send(s,buff,y,0);
//如果读取得不到1024字,就关闭文件
if(y<1024)
{
f.Close();
break;
}
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -