中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

重慶企業(yè)vi設計公司安卓優(yōu)化大師下載安裝

重慶企業(yè)vi設計公司,安卓優(yōu)化大師下載安裝,衡陽網(wǎng)站seo,織夢做的網(wǎng)站怎么上傳視頻說明 使用IO完成端口實現(xiàn)簡單回顯服務器,因為是測試用的,所以代碼很粗糙。 提醒 使用的是ReadFile、WriteFile來實現(xiàn)Overlapped IO,正式場合應該用WSARecv、WSASend,原因:來自《Windows網(wǎng)絡編程技術》 8.2.5節(jié) 在這里…

說明

使用IO完成端口實現(xiàn)簡單回顯服務器,因為是測試用的,所以代碼很粗糙。

  • 提醒
    使用的是ReadFile、WriteFile來實現(xiàn)Overlapped IO,正式場合應該用WSARecv、WSASend,原因:來自《Windows網(wǎng)絡編程技術》 8.2.5節(jié)
    在這里插入圖片描述

  • 技術點記錄下
    io以同步方式立馬完成時,系統(tǒng)也會將此通知投遞到io完成端口通知列表中,這么做的原因是方便用戶編碼。
    SetFileCompletionNotificationModes傳入FILE_SKIP_COMPLETION_PORT_ON_SUCCESS告訴系統(tǒng),io以同步方式立馬完成時,不要
    將此事件投遞到IO完成端口列表中。

    參看《Windows核心編程》第10章 10.5.4
    在這里插入圖片描述
    在這里插入圖片描述

代碼

#include <iostream>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <set>
#include <memory>
#include <process.h>#pragma comment(lib, "Ws2_32.lib")class MyOverlapped
{
public:MyOverlapped():m_bIsRead(false){memset(&m_Overlapped, 0, sizeof(OVERLAPPED));}OVERLAPPED m_Overlapped;bool m_bIsRead;
};struct ClientSocketItem
{ClientSocketItem(){hSocket = NULL;memset(szRecv, 0, sizeof(szRecv));nRecvSize = 0;bFinished = false;nWriteOffset = 0;readOverlapped.m_bIsRead = true;writeOverlapped.m_bIsRead = false;}SOCKET hSocket;std::string strIp;MyOverlapped readOverlapped;char szRecv[1024];unsigned int nRecvSize;MyOverlapped writeOverlapped;unsigned int nWriteOffset = 0;bool bFinished;
};
std::set<ClientSocketItem*> g_Clients;HANDLE g_hIoCompletionPort = NULL;bool do_read(ClientSocketItem* pClient)
{if (!pClient){return false;}char c = 0; //測試用,每次只讀一個字符DWORD dwReadBytes;if (::ReadFile((HANDLE)(pClient->hSocket), &(pClient->szRecv[pClient->nRecvSize]),1, &dwReadBytes, &(pClient->readOverlapped.m_Overlapped))){return true;}DWORD dwError = ::GetLastError();if (ERROR_IO_PENDING == dwError){return true;}std::cerr << "read failed with error " << dwError << std::endl;return false;
}bool do_write(ClientSocketItem* pClient)
{if (!pClient){return false;}//測試用,每次只發(fā)送一個字符DWORD dwWriteBytes = 0;if (::WriteFile((HANDLE)(pClient->hSocket), &(pClient->szRecv[pClient->nWriteOffset]),1, &dwWriteBytes, &(pClient->writeOverlapped.m_Overlapped))){return true;}DWORD dwError = ::GetLastError();if (ERROR_IO_PENDING == dwError){return true;}std::cerr << "write failed with error " << dwError << std::endl;return false;
}bool do_accept(SOCKET hListenSocket)
{sockaddr_in mPeerAddr = { 0 };int nAddrLen = sizeof(sockaddr);SOCKET hClientSocket = accept(hListenSocket, (sockaddr*)(&mPeerAddr), &nAddrLen);if (INVALID_SOCKET == hClientSocket){std::cout << "accept failed with error "<< WSAGetLastError() << std::endl;return false;}else{unsigned long nNoBlock = 0;ioctlsocket(hClientSocket, FIONBIO, &nNoBlock);std::string strIpAddr = inet_ntoa(mPeerAddr.sin_addr);std::cout << "accept success, peer ip is " << strIpAddr.c_str() << std::endl;auto pClient = new ClientSocketItem();pClient->hSocket = hClientSocket;pClient->strIp = strIpAddr;g_Clients.insert(pClient);//附加到IO完成端口上if (g_hIoCompletionPort != ::CreateIoCompletionPort(HANDLE(pClient->hSocket),g_hIoCompletionPort, ULONG_PTR(pClient), 0)){std::cerr << "attach socket to io completion port failed with error"<< ::GetLastError() << std::endl;closesocket(hClientSocket);return false;}//觸發(fā)讀取if (!do_read(pClient)){closesocket(pClient->hSocket);g_Clients.erase(pClient);std::cerr << "do_read failed, close client" << std::endl;}return true;}
}//讀寫線程函數(shù)
unsigned __stdcall ReadWriteThreadFun(void* pParam)
{DWORD dwTransferBytes = 0;ULONG_PTR nCompleteKey = 0;LPOVERLAPPED lpOverlapped = NULL;while (::GetQueuedCompletionStatus(g_hIoCompletionPort, &dwTransferBytes,&nCompleteKey, &lpOverlapped, INFINITE)){if (nCompleteKey == UINT_MAX){std::cout << "user require quit" << std::endl;break;}if (!lpOverlapped){std::cerr << "lpOverlapped is null" << std::endl;break;}ClientSocketItem* pClient = (ClientSocketItem*)nCompleteKey;MyOverlapped* pMyOverlapped = CONTAINING_RECORD(lpOverlapped, MyOverlapped, m_Overlapped);if (!pMyOverlapped || !pClient){std::cerr << "pMyOverlapped or pClient is null" << std::endl;break;}if (pMyOverlapped->m_bIsRead)//read finished notify{char c = pClient->szRecv[pClient->nRecvSize];pClient->nRecvSize += dwTransferBytes;std::cout << "read one char: " << c << std::endl;if (c == '\n'){std::cout << "read finished, start to write" << std::endl;if (!do_write(pClient)){std::cerr << "do_write failed, close socket" << std::endl;closesocket(pClient->hSocket);g_Clients.erase(pClient);}}else{std::cout << "next char read" << std::endl;if (!do_read(pClient)){std::cerr << "do_read failed, close socket" << std::endl;closesocket(pClient->hSocket);g_Clients.erase(pClient);}}}else //write finished notify{char c = pClient->szRecv[pClient->nWriteOffset];std::cout << "send one char: " << c << std::endl;pClient->nWriteOffset += dwTransferBytes;if (pClient->nWriteOffset == pClient->nRecvSize){std::cout << "send finished, close client(" << pClient->strIp.c_str()<< ")" << std::endl;closesocket(pClient->hSocket);g_Clients.erase(pClient);}else{std::cout << "next send" << std::endl;if (!do_write(pClient)){std::cerr << "do_write failed, close socket" << std::endl;closesocket(pClient->hSocket);g_Clients.erase(pClient);}}}}std::cout << "thread quit" << std::endl;return 0;
}int main(int argc, char* argv)
{WORD wVersionRequested = MAKEWORD(2, 2);WSADATA wsaData = { 0 };int err = WSAStartup(wVersionRequested, &wsaData);if (err != 0){return -1;}if (LOBYTE(wsaData.wVersion) != 2 ||HIBYTE(wsaData.wVersion) != 2){WSACleanup();return -1;}SOCKET hListenSocket = socket(AF_INET, SOCK_STREAM, 0);if (INVALID_SOCKET == hListenSocket){std::cerr << "create socket failed with error " << WSAGetLastError()<< std::endl;return -1;}sockaddr_in mSockAddrIn = { 0 };mSockAddrIn.sin_family = AF_INET;mSockAddrIn.sin_port = htons((u_short)8878);mSockAddrIn.sin_addr.S_un.S_addr = inet_addr("0.0.0.0");if (SOCKET_ERROR == bind(hListenSocket, (sockaddr*)(&mSockAddrIn),sizeof(sockaddr))){std::cerr << "bind failed with error " << WSAGetLastError() << std::endl;return -1;}if (SOCKET_ERROR == listen(hListenSocket, SOMAXCONN)){std::cerr << "listen failed with error " << WSAGetLastError() << std::endl;return -1;}//創(chuàng)建完成端口g_hIoCompletionPort = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);if (NULL == g_hIoCompletionPort){std::cerr << "create io completion port failed with error " << ::GetLastError() << std::endl;return -1;}//創(chuàng)建一堆服務線程for (int i = 0; i < 4; ++i){_beginthreadex(0, 0, ReadWriteThreadFun, 0, 0, nullptr);}while (true){if (!do_accept(hListenSocket)){break;}}::PostQueuedCompletionStatus(g_hIoCompletionPort, 0, UINT_MAX, nullptr);Sleep(2000); return 0;
}
http://www.risenshineclean.com/news/2735.html

相關文章:

  • 牛網(wǎng)網(wǎng)站建設互聯(lián)網(wǎng)營銷推廣怎么做
  • 蘇州市住房和城鄉(xiāng)建設局網(wǎng)站首頁手機如何做網(wǎng)站
  • 查詢建筑企業(yè)網(wǎng)站太原seo快速排名
  • 網(wǎng)站url和網(wǎng)站域名重慶森林經(jīng)典臺詞 鳳梨罐頭
  • 如何下載ppt模板免費短視頻關鍵詞seo優(yōu)化
  • 武漢市建設委員會網(wǎng)站如何使用網(wǎng)絡營銷策略
  • 電器網(wǎng)站建設策劃書百度信息流推廣技巧
  • 茂名做網(wǎng)站公司外貿(mào)營銷網(wǎng)站建設介紹
  • 優(yōu)化網(wǎng)站作用永久免費域名申請
  • 手機做網(wǎng)站多少錢中小企業(yè)管理培訓課程
  • 昆明住房和城鄉(xiāng)建設部網(wǎng)站關鍵詞制作軟件
  • 免費英文建設網(wǎng)站企點qq官網(wǎng)
  • 購買手表的網(wǎng)站百度收錄需要多久
  • 網(wǎng)站規(guī)劃明細表昆明seo關鍵字推廣
  • 如何做 試題類 網(wǎng)站百度競價投放
  • 哪些做展架圖的網(wǎng)站好代運營服務
  • 網(wǎng)站后臺是怎么做的網(wǎng)頁怎么做出來的
  • 西安網(wǎng)站建設hyk123網(wǎng)站制作培訓
  • 網(wǎng)站開發(fā)所需費用自學seo能找到工作嗎
  • seo是什么意思網(wǎng)絡用語seo外包公司哪家好
  • 專做外貿(mào)的網(wǎng)站有哪些免費十八種禁用網(wǎng)站
  • 凡客做網(wǎng)站廣州搜發(fā)網(wǎng)絡科技有限公司
  • 蘇州好的做網(wǎng)站的公司哪家好seo雙標題軟件
  • 怎樣用jsp做網(wǎng)站微信推廣平臺
  • 網(wǎng)站怎么做模板切換山東免費網(wǎng)絡推廣工具
  • 網(wǎng)站不備案支付寶接口大二網(wǎng)絡營銷實訓報告
  • 武漢城市建設學院網(wǎng)站公司廣告推廣
  • 網(wǎng)站建設制作作業(yè)外鏈優(yōu)化
  • 做網(wǎng)站為什么需要服務器關鍵詞歌詞完整版
  • 寶塔建設網(wǎng)站教程2023必考十大時政熱點