当前位置: 首页 > news >正文

朝阳区手机网站建设服务工商做年报网站

朝阳区手机网站建设服务,工商做年报网站,我想用c 来做网站,沈阳专业音响公司写在前面 此前的回声服务器/客户端都是在主线程中阻塞交互#xff0c;本文将使用多线程方式实现服务器/客户端。 互斥量相关接口 使用多线程#xff0c;自然避免不了线程同步问题。 因本文使用互斥量实现线程同步#xff0c;因此仅介绍互斥量相关接口#xff0c;其他实…写在前面 此前的回声服务器/客户端都是在主线程中阻塞交互本文将使用多线程方式实现服务器/客户端。 互斥量相关接口 使用多线程自然避免不了线程同步问题。 因本文使用互斥量实现线程同步因此仅介绍互斥量相关接口其他实现线程同步的方式如关键代码段、事件以及信号量等可自行查阅MSDN帮助文档。 创建互斥量 使用CreateMutex创建互斥量原型如下 #include windows.h HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName); 成功时返回创建的互斥量对象句柄失败返回NULL lpMutexAttributes传递安全相关的配置信息使用默认安全设置时可以传递NULL bInitialOwner如果为TRUE则创建出的互斥量对象属于调用该函数的线程同时进入non-signaled状态 如果为FALSE则创建出的互斥量对象不属于任何线程此时状态为signaled lpName: 用于命名互斥量对象。传入NULL时创建无名的互斥量对象。 销毁互斥量 互斥量属于系统内核资源使用完后需要手动释放。使用CloseHandle函数释放互斥量资源原型如下 BOOL CloseHandle(HANDLE hObject);成功时返回TRUE失败时返回FALSE hObject 要销毁的内核对象的句柄 获取互斥量 通过WaitForSingleObject接口获取互斥量原型如下 DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);hHandle对象的句柄。 如果等待仍在等待时关闭此句柄则函数的行为未定义。 dwMilliseconds超时间隔以毫秒为单位。 如果指定了非零值该函数将等待对象发出信号或间隔。 如果 dwMilliseconds 为零则如果对象未发出信号则函数不会输入等待状态;它始终会立即返回。 如果 dwMilliseconds 为 INFINITE则仅当发出对象信号时该函数才会返回。 释放互斥量 使用ReleaseMutex释放互斥量使其转变为signaled状态。 BOOL ReleaseMutex(HANDLE hMutex);成功时返回TRUE失败时返回FALSE hMutex: 需要释放解除拥有的互斥量对象句柄 多线程服务器 多线程服务器使用一个全局的socket数组维护连接的客户端socket在主线程中等待客户端的连接每有一个客户端连接时就单独开启一个线程提供回声服务使用一个全局的互斥量对象实现各提供回声服务线程的线程同步。 代码如下 // MultiThread_Server.cpp : 定义控制台应用程序的入口点。 //#include stdafx.h #include process.h #include WinSock2.h #include string #pragma comment(lib, ws2_32.lib)using namespace std;#define BUF_SIZE 100 #define MAX_CLNT 256unsigned WINAPI HandleClnt(void* arg); void SendMsg(char* arg, int len);HANDLE hMutex; int clntCnt 0; SOCKET clntSocks[MAX_CLNT];void WriteRunLog(LPCSTR lpszLog, int len);int _tmain(int argc, _TCHAR* argv[]) {if (argc ! 2){printf(argc error!\n);return -1;}WSADATA wsaData;if (0 ! WSAStartup(MAKEWORD(2, 2), wsaData)){printf(WSAStartup error!\n);return -1;}SOCKET srvSock socket(PF_INET, SOCK_STREAM, 0);if (INVALID_SOCKET srvSock){printf(socket error!\n);WSACleanup();return -1;}SOCKADDR_IN srvAddr;memset(srvAddr, 0, sizeof(srvAddr));srvAddr.sin_family PF_INET;srvAddr.sin_addr.s_addr htonl(ADDR_ANY);srvAddr.sin_port htons(_ttoi(argv[1]));if (SOCKET_ERROR bind(srvSock, (sockaddr*)srvAddr, sizeof(srvAddr))){printf(bind error!\n);closesocket(srvSock);WSACleanup();return -1;}if (SOCKET_ERROR listen(srvSock, 5)){printf(listen error!\n);closesocket(srvSock);WSACleanup();return -1;}SOCKADDR_IN cltAddr;memset(cltAddr, 0, sizeof(cltAddr));int nCltAddrSize sizeof(cltAddr);hMutex CreateMutex(NULL, FALSE, NULL);while (true){//接受连接线程nCltAddrSize sizeof(cltAddr);puts(wait for client connect...);SOCKET cltSock accept(srvSock, (sockaddr*)cltAddr, nCltAddrSize);if (cltSock INVALID_SOCKET){printf(accept error\n);continue;}//等待操作互斥量数组WaitForSingleObject(hMutex, INFINITE);clntSocks[clntCnt] cltSock;ReleaseMutex(hMutex);//最后开启该套接字的消息处理线程HANDLE hThread (HANDLE)_beginthreadex(NULL, 0, HandleClnt, (void*)cltSock, 0, NULL);printf(Connected Client IP: %s \n, inet_ntoa(cltAddr.sin_addr));}CloseHandle(hMutex);closesocket(srvSock);WSACleanup();puts(main thread end.);puts(任意键继续...);getchar();return 0; }unsigned WINAPI HandleClnt(void* arg) {SOCKET cltSock *((SOCKET*)arg);int nRecvLen 0;char Msg[BUF_SIZE] {};char Log[2*BUF_SIZE] {};while ( (nRecvLen recv(cltSock, Msg, BUF_SIZE, 0)) ! 0 ){Msg[nRecvLen] 0;//sprintf(Log, recv msg from client《%d》: %s\n, cltSock, Msg);//WriteRunLog(Log, strlen(Log));SendMsg(Msg, nRecvLen);}//若客户端断开连接则在套接字数组中清除对应socketWaitForSingleObject(hMutex, INFINITE);//找到要清除的套接字从该位置开始后续元素前移覆盖删除//双指针实现覆盖删除int slow 0;int fast 0;for (; fast clntCnt; fast){if (clntSocks[fast] cltSock){continue;}clntSocks[slow] clntSocks[fast];}clntSocks[slow] INVALID_SOCKET;clntCnt--;ReleaseMutex(hMutex);closesocket(cltSock);//sprintf(Log, Client %d Disconnected...\n, cltSock);//WriteRunLog(Log, strlen(Log));return 0;}void SendMsg(char* arg, int len) {//回复所有客户端WaitForSingleObject(hMutex, INFINITE);char Log[2*BUF_SIZE] {};for (int i 0; i clntCnt; i){//sprintf(Log, Send to client 《%d》 msg: %s\n, clntSocks[i], len);//WriteRunLog(Log, strlen(Log));send(clntSocks[i], arg, len, 0);}ReleaseMutex(hMutex); }多线程客户端 此前的回声客户端均在主线程中进行读写操作在多线程客户端中使用两个线程分别处理读写操作。 代码如下 // MultiThread_Client.cpp : 定义控制台应用程序的入口点。 //#include stdafx.h #include process.h #include WinSock2.h #pragma comment(lib, ws2_32.lib)#define BUF_SIZE 100 #define NAME_SIZE 20unsigned WINAPI SendMsg(void* arg); unsigned WINAPI RecvMsg(void* arg);char name[NAME_SIZE] [DEFAULT]; char msg[BUF_SIZE] {};int _tmain(int argc, _TCHAR* argv[]) {if (argc ! 4){printf(argc error!\n);return -1;}WSADATA wsaData;if (0 ! WSAStartup(MAKEWORD(2, 2), wsaData)){printf(WSAStartup error!\n);return -1;}printf(server ip: %s, port: %s, client name: %s\n, argv[1], argv[2], argv[3]);sprintf(name, [%s], argv[3]);SOCKET cltSock socket(PF_INET, SOCK_STREAM, 0);if (INVALID_SOCKET cltSock){puts(socket error!);WSACleanup();return -1;}SOCKADDR_IN srvAddr;memset(srvAddr, 0, sizeof(srvAddr));srvAddr.sin_family PF_INET;srvAddr.sin_addr.s_addr inet_addr(argv[1]);srvAddr.sin_port htons(_ttoi(argv[2]));if (connect(cltSock, (sockaddr*)srvAddr, sizeof(srvAddr)) SOCKET_ERROR){puts(connect error!);closesocket(cltSock);WSACleanup();return -1;}//开启客户端的接收和发送线程HANDLE hSendThread (HANDLE)_beginthreadex(NULL, 0, SendMsg, (void*)cltSock, 0, NULL);HANDLE hRecvThread (HANDLE)_beginthreadex(NULL, 0, RecvMsg, (void*)cltSock, 0, NULL);WaitForSingleObject(hSendThread, INFINITE);WaitForSingleObject(hRecvThread, INFINITE);closesocket(cltSock);WSACleanup();puts(任意键继续...);getchar();return 0; }unsigned WINAPI SendMsg(void* arg) {SOCKET cltSock *((SOCKET*)arg);char nameMsg[NAME_SIZE BUF_SIZE] {};while (true){//printf(Input Msg: );fgets(msg, BUF_SIZE, stdin);if ( !strcmp(msg, q\n) || !strcmp(msg, Q\n) ){puts(Disconnect...);break;}sprintf(nameMsg, %s %s, name, msg);send(cltSock, nameMsg, strlen(nameMsg), 0);}//exit(0);closesocket(cltSock);printf(client %d thread end.\n, cltSock);return 0; }unsigned WINAPI RecvMsg(void* arg) {SOCKET cltSock *((SOCKET*)arg);char nameMsg[NAME_SIZE BUF_SIZE] {};int nRecvLen 0;while (true){nRecvLen recv(cltSock, nameMsg, NAME_SIZE BUF_SIZE - 1, 0);if (nRecvLen -1){puts(server disconnected!);return -1;}nameMsg[nRecvLen] 0;printf(nameMsg from server: %s\n, nameMsg);}return 0; }运行结果如下 总结 虽然使用互斥量实现了简单的多线程服务器/客户端但也只是借此熟悉下线程及线程同步相关的接口可以明显的看到效率还是比较低下的。 要想使用高效的Windows服务器客户端可以使用IOCP完成端口实现。
http://www.w-s-a.com/news/17956/

相关文章:

  • 网站建设丿金手指谷哥14阿里巴巴官网电脑版
  • 网站开发招聘信息匿名ip访问网站受限
  • 网站转app工具网站规划建设与管理维护大作业
  • flash是怎么做网站的.net购物网站开发
  • 烟台网站建设求职简历品质商城网站建设
  • 做百度外链哪些网站权重高点做网站具备的条件
  • 怎么样用ppt做网站红番茄 网站点评
  • 建设银行河北分行招聘网站哪里能找到网站
  • 兰州营销型网站网站建设收费标准
  • 网站首页动图怎么做自己做网站很难
  • 自建网站如何盈利推广引流最快的方法
  • 网页设计网站结构图怎么弄网站用户 分析
  • 企业手机网站建设策划天津网页设计工作
  • 苏州vr全景网站建设公司怎么讲解网页的制作技术
  • 徐州智能建站怎么做苏州建设网站首页
  • 网站支付功能报价wordpress主页透明
  • asia域名的网站宁波模板建站源码
  • 官网网站怎么做个人网站盈利
  • 青龙桥网站建设网站同时做竞价和优化可以
  • 沭阳建设网站婴儿辅食中企动力提供网站建设
  • 常州做网站的公司济宁网站建设seo
  • 用wordpress做企业网站视频教程韶关建设网站
  • 怎么做一个免费的网站云南网站设计选哪家
  • dw做六个页面的网站做网站运营有前途吗
  • 中级网站开发工程师 试题战地之王网站做任务
  • 广东东莞保安公司湖南 seo
  • 无锡网站策划公司如何零基础学编程
  • 金融网站如何做设计网站开发流程 文档
  • 用jsp做网站国内知名设计工作室
  • 一键搭建网站北京公司网站设计