這幾天一直在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;}搭建好最底層的框架后,接下來就是創建自己所需要的類來完成服務器與客戶端的通信。
新聞熱點
疑難解答
圖片精選