select + 线程池 回应服务器(windows)

//为了支持移植 沿用Ptypes的头文件
#define WIN32 1
#include "ptime.h"
#include "pinet.h"
#include "ptypes.h"
#include "pasync.h"#ifdef WIN32
#pragma comment(lib, "ptypes.lib")
#pragma comment(lib, "ws2_32.lib")
#endif#ifdef WIN32
#  include <winsock2.h>
#else
#  include <sys/time.h>
#  include <sys/types.h>
#  include <sys/socket.h>
#  include <netinet/in.h>
#  include <arpa/inet.h>
#  include <netdb.h>
#  include <unistd.h>
#  include <time.h>
#endifUSING_PTYPESconst int testport = 8101;
const int maxtoken = 4096;
const int timeout = -1;
const int maxsetsize = 1024*10;
const int maxthreads = 30;const int MSG_MYJOB = MSG_USER + 1;fd_set g_allset;  //保存所有要检测的socket;
int g_arrClientSocket[maxsetsize];
struct SocketInfo
{int nSocket;int nIndex;
};class myjobthread: public thread
{
protected:int id;jobqueue* jq;virtual void execute();
public:myjobthread(int iid, jobqueue* ijq): thread(false), id(iid), jq(ijq)  {}~myjobthread()  { waitfor(); }
};class myjob: public message
{
public:SocketInfo* m_pSocketInfo;myjob(SocketInfo* pSocketInfo): message(MSG_MYJOB), m_pSocketInfo(pSocketInfo)  {}~myjob()  {delete m_pSocketInfo; }
};void myjobthread::execute()
{bool quit = false;while (!quit){// get the next message from the queuemessage* msg = jq->getmessage();try{switch (msg->id){case MSG_MYJOB:{pout.putf("%t,线程:%d\n", now(), id);int nClientSocket = ((myjob*)msg)->m_pSocketInfo->nSocket;int nIndex = ((myjob*)msg)->m_pSocketInfo->nIndex;BYTE buffer[maxtoken];memset(buffer, 0x00, sizeof(buffer));int nLen1=0,nLen2 = 0,nRemainLen=0;nLen1 = ::recv(nClientSocket, (char*)buffer, maxtoken, 0);//nLen1 = ::recv(nClientSocket, (char*)buffer, sizeof(UINT32)*3, 0);pout.putf("%t,%d接收到nLen1:%d字节\n", now(),id, nLen1);if (nLen1 <= 0){//客户端关闭g_arrClientSocket[nIndex] = -1;FD_CLR(nClientSocket,&g_allset);::closesocket(nClientSocket);pout.putf("%t, %d关闭socket:%d\n", now(), id, nClientSocket);break;}int nSend = ::send(nClientSocket, (char*)buffer, nLen1, 0);pout.putf("%t,%d返回:%d字节\n",now(), id, nSend);}break;case MSG_QUIT:// MSG_QUIT is not used in our examplequit = true;break;}}catch(exception*){// the message object must be freed!delete msg;throw;}delete msg;}
}int main()
{//启动线程池jobqueue jq;tobjlist<myjobthread> threads(true);// create the thread poolfor(int n = 0; n < maxthreads; n++){myjobthread* j = new myjobthread(n + 1, &jq);j->start();threads.add(j);}int nReady = 0;int nMaxfd = 0;int nMaxi = 0;int nSvrSocket;int  nConSocket; //int nClientSocket;sockaddr_in clientaddr;  //客户端地址;int nCaLen;      //客户端地址长度int i;           //循环用#ifdef WIN32WSADATA wsaData;int iError = WSAStartup(MAKEWORD(2,0), &wsaData);if (iError != 0){return false;}if ( LOBYTE( wsaData.wVersion ) < 2 ) {WSACleanup();return false; }//nSvrSocket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
#endifnSvrSocket = ::socket(AF_INET, SOCK_STREAM, 0);if (nSvrSocket < 0){pout.putf("Couldn't create socket!\n");return false;}#ifndef WIN32// set SO_REAUSEADDR to true, unix only. on windows this option causes// the previous owner of the socket to give up, which is not desirable// in most cases, neither compatible with unix.int one = 1;if (::setsockopt(svrSocket, SOL_SOCKET, SO_REUSEADDR,(sockval_t)&one, sizeof(one)) != 0)pout.putf("Can't reuse local address!\n");
#endif// set up sockaddr_in and try to bind it to the socketsockaddr_in sa;memset(&sa, 0, sizeof(sa));sa.sin_family = AF_INET;sa.sin_port = htons(testport);sa.sin_addr.S_un.S_addr = INADDR_ANY;if (::bind(nSvrSocket, (sockaddr*)&sa, sizeof(sa)) != 0){#ifdef WIN32WSACleanup();#endifpout.putf("Couldn't bind address!\n");return -1;}if (::listen(nSvrSocket, SOMAXCONN) != 0){#ifdef WIN32WSACleanup();#endif		pout.putf("Couldn't listen on socket!\n");return -1;}pout.putf("Ready to answer queries on port %d\n", testport);//初始化变量nMaxfd = nSvrSocket;nMaxi = 0;for (i =0; i < maxsetsize; i++){g_arrClientSocket[i] = -1;}fd_set set;FD_ZERO(&g_allset); //初始化给情空;FD_SET(nSvrSocket,&g_allset);//设定超时时间timeval t;t.tv_sec = timeout / 1000;t.tv_usec = (timeout % 1000) * 1000;while(true){set = g_allset;nReady = ::select(nMaxfd + 1, &set, nil, nil,(timeout < 0) ? nil : &t);if (nReady <= 0) continue;if (FD_ISSET(nSvrSocket, &set)){nCaLen = sizeof(clientaddr);nConSocket = ::accept(nSvrSocket,(sockaddr*)&clientaddr,&nCaLen);if (nConSocket < 0){pout.putf("Couldn't listen on socket!\n"); continue;				}//打印连接的客户端。pout.putf("%t连接进来的IP: %s! Port:%d\n",now(),inet_ntoa(clientaddr.sin_addr),ntohs((unsigned short)clientaddr.sin_port));//pout.putf("连接进来的IP: %s! Port:%d\n",inet_ntoa(AF_INET, &clientaddr.sin_addr, 4, NULL),ntohs(clientaddr.sin_port)); //设定超时时间和缓存区;int nNetTimeOut= 300000; //5分////int time, nlen;//::getsockopt(nConSocket, SOL_SOCKET, SO_SNDTIMEO, (char *)&time, &nlen);// pout.putf("timeout%d!\n",time); //::getsockopt(nConSocket, SOL_SOCKET, SO_RCVBUF, (char *)&time, &nlen);//pout.putf("SO_RCVBUF%d!\n",time);//::getsockopt(nConSocket, SOL_SOCKET, SO_SNDBUF, (char *)&time, &nlen);//pout.putf("SO_SNDBUF%d!\n",time);//::setsockopt(nConSocket, SOL_SOCKET, SO_SNDTIMEO, (char *)&nNetTimeOut, sizeof(nNetTimeOut));::setsockopt(nConSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&nNetTimeOut, sizeof(nNetTimeOut));int nBufLen = 1024;::setsockopt(nConSocket, SOL_SOCKET, SO_RCVBUF, (char *)&nBufLen, sizeof(nBufLen));::setsockopt(nConSocket, SOL_SOCKET, SO_SNDBUF, (char *)&nBufLen, sizeof(nBufLen));for (i = 0; i < maxsetsize; i++){ if (g_arrClientSocket[i] < 0){g_arrClientSocket[i] = nConSocket;break;}				}if (i == maxsetsize -1){//太多的连接pout.putf("too many clients!\n"); }FD_SET(nConSocket, &g_allset); //把新的连接加到集合里。if (nConSocket > nMaxfd){nMaxfd = nConSocket;}if (i > nMaxi)nMaxi = i;				/* max index in client[] array */if (--nReady <= 0)continue;				/* no more readable descriptors */}pout.putf("\nbegin:%t:%d  %d\n", now(), msecs(now()),nMaxi);for (i = 0; i <= nMaxi; i++){//nClientSocket = g_arrClientSocket[i];if (g_arrClientSocket[i]< 0) continue;if (FD_ISSET(g_arrClientSocket[i], &set)){//接收和发送pout.putf("%t抛 socket 到线程池%d:%d!\n",now(),i,g_arrClientSocket[i]); struct SocketInfo* pSocketInfo = new SocketInfo;pSocketInfo->nIndex = i;pSocketInfo->nSocket = g_arrClientSocket[i];jq.post(new myjob(pSocketInfo));if (--nReady <= 0)break;				/* no more readable descriptors */}}//pout.putf("end:%t:%d\n", now(), msecs(now()));}closesocket(nSvrSocket);#ifdef WIN32WSACleanup();#endifreturn 0;};


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/462404.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个程序员的创业失败教训

原文链接 http://blog.jobbole.com/6752/ 这段经历是悲伤的&#xff0c;也是快乐的&#xff0c;毕竟创业是充满激情的&#xff0c;想着自己以后可以不再给人打工了&#xff0c;可以给自己打工了&#xff0c;一个程序员写了很多年的程序之后&#xff0c;能够有机会给自己写程序&…

学习《深度学习入门:基于Python的理论与实现》高清中文版PDF+源代码

入门神经网络深度学习&#xff0c;推荐学习《深度学习入门&#xff1a;基于Python的理论与实现》&#xff0c;这本书不来虚的&#xff0c;一上来就是手把手教你一步步搭建出一个神经网络&#xff0c;还能把每一步的出处讲明白。理解神经网络&#xff0c;很容易就能入门。 深度学…

每日英文2013.06.19

1.contact /ˈkɑnˌtkt/ v. 接觸;聯繫 (1) Customers may contact any of our location to inquire about car rentals. a.inquire /ɪnˈkwaɪr/ v. to ask someone for information about something b.rental /ˈrent(ə)l/ n. an amount of money that you pay for rentin…

JavaScript 刷新当前页面

1 history.go(0) 2 location.reload() 3 locationlocation 4 location.assign(location) 5 document.execCommand(Refresh) 6 window.navigate(location) 7 location.replace(location) 8 document.URLlocation.href 转载于:https://www.cnblogs.com/SUPERAI/archive/2011/11/2…

学习《PythonWeb开发实战(董伟明)》中文PDF+源代码

python可以用了进行数据分析&#xff0c;也可以进行Web开发&#xff0c;一般会使用django或者flask等进行开发。 国内介绍python web的书有写的不错的&#xff0c;推荐看看《PythonWeb开发实战》 他的定位是进阶读者&#xff0c;介绍了Python web的生态&#xff0c;有些包介绍得…

周鸿祎:在360新员工入职培训上的讲话

这个是周鸿祎给入司360新员工的一段话&#xff0c;不但适合360&#xff0c;也适合所有的公司员工。特此分享。我想给新入职的同事讲一讲我的期望&#xff0c;再提几个建议。我这个人喜欢说真话&#xff0c;不喜欢说漂亮话&#xff0c;因为漂亮话没用。但说真话&#xff0c;大家…

file_exists函数总是返回false

今天在一台开发服务器上遇到一个奇怪的问题&#xff0c;通过WEB方式访问PHP程序 file_exists() 总是返回false&#xff0c;试了很多文件和目录都不行。开始以为是 safe mode 的问题&#xff0c;但是 php.ini 中的safe_mode 选项值是 Off。接着又在命令行以 root 账号执行测试程…

简单的web框架(python)

1、web框架介绍 Web框架&#xff08;Web framework&#xff09;是一种开发框架&#xff0c;用来支持动态网站、网络应用和网络服务的开发。这大多数的web框架提供了一套开发和部署网站的方式&#xff0c;也为web行为提供了一套通用的方法。web框架已经实现了很多功能&#xff0…

set_bit() 等位函数分析! \linux-1.0\linux\include\asm\bitops.h

//将addr的第nr(nr为0-31)位置值置为1; //nr大于31时&#xff0c;把高27的值做为当前地址的偏移&#xff0c;低5位的值为要置为1的位数 extern __inline__ int set_bit(int nr,int * addr) { int mask, retval; addr nr >> 5; //nr大于31时&…

使用面向对象技术创建高级 Web 应用程序

作者&#xff1a; 出处&#xff1a; 使用面向对象技术创建高级 Web 应用程序 来源:开源中国社区 作者:oschina最近&#xff0c;我面试了一位具有5年Web应用开发经验的软件开发人员。她有4年半的JavaScript编程经验&#xff0c;自认为自己具有非常优秀的JavaScript技能&#xff…

[翻译]DirectX 状态( 转)

[翻译]DirectX 状态状态 Direct3D设备使用状态来配置所有的管道处理。采样器状态通过例如定义纹理寻址方式(texture addressing)和过滤模式控制纹理采样器设置。纹理状态设置用于控制纹理如何被组合以及相互之间如何混合的多重纹理混合器。渲染状态控制大多数管道状态。 状态块…

【转载】浅谈React编程思想

React是Facebook推出的面向视图层开发的一个框架&#xff0c;用于解决大型应用&#xff0c;包括如何很好地管理DOM结构&#xff0c;是构建大型&#xff0c;快速Web app的首选方式。 React使用JavaScript来构建用户界面&#xff0c;因此可以说是一个用来构建用户界面的JavaScrip…

a.out.h 头文件分析 \linux-1.0\linux\include\linux\a.out.h

#ifndef __A_OUT_GNU_H__ #define __A_OUT_GNU_H__#define __GNU_EXEC_MACROS__#ifndef __STRUCT_EXEC_OVERRIDE__//定义执行文件结构 struct exec {unsigned long a_info; /* Use macros N_MAGIC, etc for access */unsigned a_text; /* length of text, in bytes */unsigne…

[TypeScript] vs code TSLint常见错误解决方案

TSLint是一个Typescrip{过滤}t验证工具&#xff0c;用于检测代码。 TSLint: comment must start with a space (comment-format)注释必须从一个空格开始(comment-format)也就是说//之后必须跟随一个空格。“Missing semicolon.” : “缺少分号.”,“Use the function form of \…

ios开发笔记之 线程间通信

performSelectorOnMainThread:selector:waitUntilDone: 用于线程间通信 使两个线程同步或者时异步执行。 block阻塞转载于:https://www.cnblogs.com/vincent-lu/archive/2011/11/29/2267974.html

SQL Cookbook—数字、日期

1、计算不包含最大值和最小值的均值2、把字母数字串转换为数值3、更改累计和中的值–显示存款或取款后的值4、加减日、月、年5、计算两个日期之间的天数6、确定两个日期之间的工作日数目表EMP中&#xff0c;计算BLAKE和JONES的hiredate&#xff08;聘用日期&#xff09;之间的工…

file_table.c 文件分析 linux1_0\linux\fs\file_table.c

/** linux/fs/file_table.c** Copyright (C) 1991, 1992 Linus Torvalds*/#include <linux/fs.h> #include <linux/string.h> #include <linux/mm.h>struct file * first_file; //开头文件. int nr_files 0; //文件位置为0//文件双向链表插入文…

Day 16 包 json模块和os模块

目录 包什么是包包被导入时发生的三件事包和模块的区别相对路径和绝对路径json模块OS模块列出目录下所有文件重命名文件删除文件拼接路径判断是否为文件判断是否为文件夹判断文件是否存在新建文件夹包 什么是包 包就是里一个文件夹,里面存放了多个模块,并且包会自带__init__.py…

人的左右脑

右脑支配左手、左脚、左耳等人体的左半身神经和感觉&#xff0c;而左脑支配右半身的神经和感觉&#xff0c;正如实验一所表明的&#xff0c;右视野同左脑&#xff0c;左视野同右脑相连。因为语言中枢在左脑&#xff0c;所以左脑主要完成语言的、逻辑的、分析的、代数的思考认识…

DevExpress控件使用经验总结

DevExpress控件使用经验总结 DevExpress是一个比较有名的界面控件套件&#xff0c;提供了一系列的界面控件套件的DotNet界面控件。本文主要介绍我在使用DevExpress控件过程中&#xff0c;遇到或者发现的一些问题解决方案&#xff0c;或者也可以所示一些小的经验总结。总体来讲&…