这几天一直在c++里写一个ABCBank项目,项目的总体框架和之前写的聊天室或多或少都有些相似的地方,但又大不相同,毕竟一个是c一个是c++,而且这是服务器也即是银行职工与客户之间的直接操作关系,不是客户与客户之间的交流平台。首先,搭建好能使客户与服务器间操作的平台,和c一样,同样需要创建套接口,初始化服务器结构,绑定,监听,连接这几个流程,不过c++中多了一个检查协议栈安装的步骤,这是必不可少的一项内容,下面是服务器和客户端的代码,客户端共有两个线程,一个用来读,一个用来写(传递消息,接受消息):
服务器:
void WSA()//检查协议栈安装情况
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return ;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||HIBYTE( wsaData.wVersion ) != 2 )
{
WSACleanup( );
return ;
}
}
int main()
{
WSA();
//创建监听套接口
SOCKET listenfd;
listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listenfd == INVALID_SOCKET)
{
cout<<"1error with code = "<<WSAGetLastError()<<endl;
//exit(1);
}
//初始化服务器地址结构
sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(8888);
//绑定本地地址和端口号
int ret = bind(listenfd, (sockaddr*)&servaddr, sizeof(servaddr));
if (ret == SOCKET_ERROR)
{
cout<<"2error with code = "<<WSAGetLastError()<<endl;
//exit(1);
}
//监听套接字
ret = listen(listenfd, SOMAXCONN);
if (ret == SOCKET_ERROR)
{
cout<<"3error with code = "<<WSAGetLastError()<<endl;
//exit(1);
}
sockaddr_in peeraddr;
while (1)
{
int peerlen = sizeof(peeraddr);
//等待客户端的连接
SOCKET con = accept(listenfd, (sockaddr*)&peeraddr, &peerlen);
if (con == INVALID_SOCKET)
{
cout<<"对不起,连接失败 原因是: "<<WSAGetLastError()<<endl;
exit(1);
}
cout<<inet_ntoa(peeraddr.sin_addr)<<" "<<ntohs(peeraddr.sin_port)<<endl;
// 客户端连接上, 进行通信,通信使用新的套接字
DWORD ThreadID;
HANDLE handle = CreateThread(NULL,0,server_request,(LPVOID )con ,0,&ThreadID);
if(NULL == handle)
{
cout<<"错误原因是"<<GetLastError()<<endl ;
exit(1);
}
WaitForSingleObject(handle,0);
CloseHandle(handle);
}
WSACleanup();
return 0 ;
}
客户端:
void WSA()//检查协议栈安装情况
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return ;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||HIBYTE( wsaData.wVersion ) != 2 )
{
WSACleanup( );
return ;
}
}
int main(void)
{
WSA() ;
//创建监听套接口
SOCKET sock;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
cout<<"error with code = "<<WSAGetLastError()<<endl;
exit(1);
}
//初始化服务器地址结构
sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(8888);
//连接服务器
int ret;
ret = connect(sock, (sockaddr*)&servaddr, sizeof(servaddr));
if (ret == -1)
{
cout<<"2error with code = "<<WSAGetLastError()<<endl;
exit(1);
}
DWORD ThreadID;//创建一个线程用来读服务器发过来的消息
HANDLE handle = CreateThread(NULL,0,readinfor,(LPVOID )sock ,0,&ThreadID);
if(NULL == handle)
{
cout<<"错误原因是"<<GetLastError()<<endl ;
exit(1);
}
WaitForSingleObject(handle,0);
CloseHandle(handle);
writeinfor(sock);//写消息给服务器
closesocket(sock);
return 0;
}
搭建好最底层的框架后,接下来就是创建自己所需要的类来完成服务器与客户端的通信。