iocp 小例子
2016-08-3116:44:09
server 端
- /*******************************************************************
- author:xuqing
- date:2016-5-20
- about the io thread
- the init part must be less than 1000,just the real_part_count
- THREAD_DEAL_COUNT is the count one thread can deal with
- if the real_part_count is 10;
- the THREAD_DEAL_COUNT is 5
- we just need 2 thread to deal the all io write
- success return 0
- error return 负数
- sucess 有意义 正数
- ***********************************************************************/
- #include "stdafx.h"
- #include "rts_server.h"
- #include "memory_part.h"
- #pragma comment(lib,"ws2_32.lib")
- #define THREAD_DEAL_COUNT 5
- HANDLE h_complete_point;
- extern memory_part *temp_memory[];
- int socket_init()
- {
- RTS_DIARY_RET_ERROR_VAR;
- WSAData wsaData;
- if (WSAStartup(MAKEWORD(, ), &wsaData) != )
- {
- printf("WSAStartup失败!\n");
- RTS_DIARY_ERROR_GOTO;
- }
- if (LOBYTE(wsaData.wVersion) != || HIBYTE(wsaData.wVersion) != )
- {
- printf("版本不对!\n");
- RTS_DIARY_ERROR_GOTO;
- }
- return ;
- ret_error:
- if (i_ret) return i_ret;
- return ;
- }
- int write_memory(char *record)
- {
- RTS_DIARY_RET_ERROR_VAR;
- char str_cust_id[];
- get_custid2data(record, str_cust_id);
- int int_cust_id = atoi(str_cust_id);
- int part_index = int_cust_id % MAX_PART;
- memory_part *save_part = temp_memory[part_index];
- if (save_part == NULL) RTS_DIARY_ERROR_GOTO;
- SqQueue *save_queue = save_part->queue_offset;
- if (save_queue == NULL) RTS_DIARY_ERROR_GOTO;
- if ((save_queue->rear + ) % MAX_RECORD_OF_PART == save_queue->front)
- {
- //write memory wait!!!
- Sleep();
- }
- i_ret=save_data2memory(part_index, record);
- if (i_ret != ) RTS_DIARY_ERROR_GOTO;
- return ;
- ret_error:
- if (i_ret) return i_ret;
- return ;
- }
- DWORD WINAPI ServerWorkerThread(LPVOID CompletionPort)
- {
- RTS_DIARY_RET_ERROR_VAR;
- HANDLE ComPort = (HANDLE)CompletionPort;
- DWORD BytesTransferred;
- //LPOVERLAPPED Overlapped;
- LPPER_HANDLE_DATA PerHandleData;
- LPPER_IO_OPERATION_DATA PerIoData;
- DWORD SendBytes, RecvBytes;
- DWORD Flags;
- int recv_int;
- char str[] = "";
- while (TRUE)
- {
- //等待完成端口上SOCKET的完成 阻塞
- printf( "等待完成端口上SOCKET的完成!\n");
- if ((GetQueuedCompletionStatus(ComPort,&BytesTransferred, (PULONG_PTR)&PerHandleData,(LPOVERLAPPED *)&PerIoData, INFINITE)) == NULL)
- {
- continue;
- }
- recv_int = BytesTransferred;
- printf("BytesTransferred work:%d\n", BytesTransferred);
- //检查是否有错误产生
- if (BytesTransferred == &&(PerIoData->OperationType == RECV_POSTED ||PerIoData->OperationType == SEND_POSTED))
- {
- //关闭SOCKET
- printf("%d SOCKET关闭\n", PerHandleData->sock);
- closesocket(PerHandleData->sock);
- free(PerHandleData);
- free(PerIoData);
- continue;
- }
- //为请求服务
- if (PerIoData->OperationType == RECV_POSTED)
- {
- printf( "接收处理\n");
- memcpy(str, PerIoData->Buff, recv_int);
- str[recv_int] = '\0';
- printf("%d SOCKET :%s\n", PerHandleData->sock, str);
- //although it is multithread but they don't visit the same memory,we have use the queue structure to avoid it
- write_memory(str);
- ZeroMemory(PerIoData->Buff, );
- strcpy(PerIoData->Buff, str);
- Flags = ;
- ZeroMemory((LPVOID)&(PerIoData->Overlapped), sizeof(OVERLAPPED));
- PerIoData->DataBuff[].len = ;
- PerIoData->DataBuff[].buf = PerIoData->Buff;
- PerIoData->OperationType = SEND_POSTED;
- WSASend(PerHandleData->sock, PerIoData->DataBuff,, &SendBytes, , &(PerIoData->Overlapped), NULL);
- printf("the send byte is %d\n", SendBytes);
- }
- else //if(PerIoData->OperationType == SEND_POSTED)
- {
- printf( "发送处理!\n");
- Flags = ;
- ZeroMemory((LPVOID)&(PerIoData->Overlapped), sizeof(OVERLAPPED));
- ZeroMemory(PerIoData->Buff, );
- PerIoData->DataBuff[].len = ;
- PerIoData->DataBuff[].buf = PerIoData->Buff;
- PerIoData->OperationType = RECV_POSTED;
- WSARecv(PerHandleData->sock, PerIoData->DataBuff,, &RecvBytes, &Flags, &(PerIoData->Overlapped), NULL);
- //recv_int = RecvBytes;
- printf("the recv byte is %d\n", RecvBytes);
- }
- }
- return ;
- ret_error:
- if (i_ret) return i_ret;
- return ;
- }
- DWORD WINAPI write_disk(LPVOID p)
- {
- RTS_DIARY_RET_ERROR_VAR;
- Sleep();
- //循环处理不同的part 一个线程可以负责处理多个不同的part
- memory_part *write_part;
- SqQueue *queue;
- int i = (int)p;
- while (true)
- {
- write_part = temp_memory[i];
- queue = write_part->queue_offset;
- if (write_part == NULL || queue == NULL) continue;
- printf("rear : %d, front :%d", queue->rear, queue->front);
- while (true)
- {
- if (queue->front != (queue->rear))
- {
- printf("while front %d\n", queue->front);
- printf("hello\n");
- save_data2disk(+i);
- }
- else
- {
- //if the read thread pointer==write thread pointer
- //the read thread must sleep 500
- Sleep();
- break;
- }
- }
- i = i + ;
- i = i % THREAD_DEAL_COUNT + (int)p;
- }
- return ;
- ret_error:
- if (i_ret) return i_ret;
- return ;
- }
- int start_rts_server()
- {
- RTS_DIARY_RET_ERROR_VAR;
- LPPER_HANDLE_DATA perHandleData;
- LPPER_IO_OPERATION_DATA ioperdata;
- SYSTEM_INFO siSys;
- SOCKET sockListen;
- struct sockaddr_in addrLocal;
- int nRet = ;
- DWORD nThreadID;
- SOCKET sockAccept;
- DWORD dwFlags;
- DWORD dwRecvBytes;
- int nReuseAddr = ;
- int ret_code = ;
- int real_part_count = ;
- printf("初始环境...!\n");
- if (socket_init() != ) RTS_DIARY_ERROR_GOTO;
- init_memory_part(real_part_count);
- //创建一个IO完成端口
- printf("创建一个IO完成端口!\n");
- h_complete_point = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, , );
- if (h_complete_point == INVALID_HANDLE_VALUE)
- {
- printf("创建IO完成端口失败!\n");
- RTS_DIARY_ERROR_GOTO;
- }
- //获取CPU数目
- GetSystemInfo(&siSys);
- for (int i = ; i<(int)siSys.dwNumberOfProcessors * ; i++)//NumberOfProcessors
- {
- HANDLE hThread;
- hThread = CreateThread(NULL, , ServerWorkerThread, (LPVOID)h_complete_point, , &nThreadID);
- printf("创建工作者线程 ---->%d!\n", i);
- CloseHandle(hThread);
- }
- //创建监听SOCKET
- printf("创建监听SOCKET!\n");
- sockListen = WSASocket(AF_INET, SOCK_STREAM, , NULL, , WSA_FLAG_OVERLAPPED);
- if (sockListen == SOCKET_ERROR)
- {
- printf("WSASocket错误!\n");
- RTS_DIARY_ERROR_GOTO;
- }
- if (setsockopt(sockListen, SOL_SOCKET, SO_REUSEADDR, (const char *)&nReuseAddr, sizeof(int)) != )
- {
- printf("setsockopt错误!\n");
- RTS_DIARY_ERROR_GOTO;
- }
- addrLocal.sin_family = AF_INET;
- addrLocal.sin_addr.s_addr = htonl(INADDR_ANY);
- addrLocal.sin_port = htons();
- if (bind(sockListen, (struct sockaddr *)&addrLocal, sizeof(sockaddr_in)) != )
- {
- printf("bind错误\n");
- i_ret = WSAGetLastError();
- RTS_DIARY_ERROR_GOTO;
- }
- //准备监听
- printf("准备监听\n");
- if (listen(sockListen, ) != )
- {
- printf("listen错误\n");
- RTS_DIARY_ERROR_GOTO;
- }
- int client_addr = sizeof(SOCKADDR_IN);
- int index_part = ;
- // the thread to save data into the disk
- for (int i = ; i < real_part_count / THREAD_DEAL_COUNT;i++)
- {
- index_part = THREAD_DEAL_COUNT*i;
- HANDLE write_handle = CreateThread(NULL, , write_disk,(LPVOID)index_part, , NULL);
- }
- //main thread to get client accept
- while (true)
- {
- //阻塞
- sockAccept = WSAAccept(sockListen, NULL, NULL, NULL, );
- perHandleData = (LPPER_HANDLE_DATA)malloc(sizeof(PER_HANDLE_DATA));
- if (perHandleData == NULL) continue;
- printf("socket number ---> %d 接入!\n", sockAccept);
- perHandleData->sock = sockAccept;
- if (CreateIoCompletionPort((HANDLE)sockAccept, h_complete_point, (ULONG_PTR)perHandleData, ) == NULL)
- {
- free(perHandleData);
- printf("iocp client!\n");
- continue;
- }
- ioperdata = (LPPER_IO_OPERATION_DATA)malloc(sizeof(PER_IO_OPERATION_DATA));
- memset(&(ioperdata->Overlapped), , sizeof(OVERLAPPED));
- (ioperdata->DataBuff[]).len = ;
- (ioperdata->DataBuff[]).buf = ioperdata->Buff;
- ioperdata->OperationType = RECV_POSTED;
- if (ioperdata == NULL)
- {
- free(perHandleData);
- continue;
- }
- printf("投递接收操作!\n");
- dwFlags = ;
- int b=WSARecv(perHandleData->sock, &ioperdata->DataBuff[], , &dwRecvBytes, &dwFlags, &(ioperdata->Overlapped), NULL);
- printf("the recv byte main():%d \n", dwRecvBytes);
- if (b == SOCKET_ERROR)
- {
- ret_code = WSAGetLastError();
- if (ret_code= WSA_IO_PENDING)
- {
- printf("was recv sucess %d\n", WSAGetLastError());
- }
- else
- {
- printf("was recv error!\n");
- RTS_DIARY_ERROR_GOTO;
- }
- }
- }
- ret_error:
- if (i_ret) return i_ret;
- closesocket(sockListen);
- return ;
- }
client 端
- #include "stdafx.h"
- #include "rts_client.h"
- #pragma comment(lib,"ws2_32.lib")
- SOCKET sockClient;
- struct sockaddr_in addrServer;
- char buf[1024];
- int n = 0;
- int socket_init()
- {
- WSAData wsaData;
- if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
- {
- printf("WSAStartup失败!\n");
- return -1;
- }
- if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
- {
- printf("版本不对!\n");
- WSACleanup();
- return -1;
- }
- return 0;
- }
- DWORD WINAPI recv_thread(LPVOID par)
- {
- while (true)
- {
- if (recv(sockClient, buf, 1024, 0) <= 0)
- {
- printf("recv失败,可能连接断开!\n");
- //break;
- goto theend;
- }
- printf("服务器应答:%s", buf);
- memset(buf, 0, 1024);
- Sleep(200);
- }
- theend:
- WSACleanup();
- getchar();
- return 0;
- }
- int client_start()
- {
- int i_ret_error = 0;
- ff2028_gset_ctx_t gset_st;
- ff2028_gset_ctx_t *p_gset_st=&gset_st;
- unsigned char tag[4];
- i_ret_error = ff2028_gset_ctx_init(p_gset_st);
- if (i_ret_error < 0)
- {
- printf("error-> %s,%s,%d\n", __FILE__, __FUNCTION__, __LINE__);
- return i_ret_error - __LINE__;
- }
- if (socket_init() != 0)
- goto theend;
- sockClient = socket(AF_INET, SOCK_STREAM, 0);
- if (sockClient == INVALID_SOCKET)
- {
- printf("socket 失败!\n");
- WSACleanup();
- goto theend;
- }
- memset(&addrServer, 0, sizeof(sockaddr_in));
- addrServer.sin_family = AF_INET;
- addrServer.sin_addr.s_addr = inet_addr("127.0.0.1");
- addrServer.sin_port = htons(9090);
- printf("连接服务器...\n");
- if (connect(sockClient, (const struct sockaddr *)&addrServer, sizeof(sockaddr)) != 0)
- {
- printf("connect 失败\n");
- WSACleanup();
- goto theend;
- }
- memset(buf, 0, 1024);
- sprintf(buf, "1005,5443543546546,,6566,4564645646546,t435435345353453534535 --->%d\r\n", n);
- tag[0] = 100;
- i_ret_error = ff2028_gset_add_app_data(p_gset_st, tag, 1, (unsigned char *)buf, strlen(buf));
- if (i_ret_error < 0)
- {
- printf("error-> %s,%s,%d\n", __FILE__, __FUNCTION__, __LINE__);
- return i_ret_error - __LINE__;
- }
- ff2028_gset_add_app_data_end(p_gset_st);
- //HANDLE receive = CreateThread(NULL, 0, recv_thread, NULL, 0, NULL);
- while (true)
- {
- sprintf(buf, "1005,5443543546546,,6566,4564645646546,t435435345353453534535 --->%d\r\n", n);
- if (send(sockClient, buf, strlen(buf), 0) <= 0)
- {
- printf( "send失败,可能连接断开!\n");
- //break;
- goto theend;
- }
- memset(buf, 0, 1024);
- //接收服务端应答
- if (recv(sockClient, buf, 1024, 0) <= 0)
- {
- printf("recv失败,可能连接断开!\n");
- //break;
- goto theend;
- }
- printf("服务器应答:%s", buf);
- memset(buf, 0, 1024);
- Sleep(200);
- n++;
- if (n == 20)
- break;
- }
- theend:
- WSACleanup();
- return 0;
- }
iocp 小例子的更多相关文章
- springmvc入门的第一个小例子
今天我们探讨一下springmvc,由于是初学,所以简单的了解一下 springmvc的流程,后续会持续更新... 由一个小例子来简单的了解一下 springmvc springmvc是spring框 ...
- java即时通信小例子
学习java一段时间了,今天写来一个即时通信的小例子练手在其过程中也学到了一些知识拿出来和大家分享,请路过的各位大神多多赐教... 好了下面讲一下基本的思路: 首先,编写服务器端的程序,简单点说吧就是 ...
- Runtime的几个小例子(含Demo)
一.什么是runtime(也就是所谓的“运行时”,因为是在运行时实现的.) 1.runtime是一套底层的c语言API(包括很多强大实用的c语言类型,c语言函数); [runti ...
- bootstrap 模态 modal 小例子
bootstrap 模态 modal 小例子 <html> <head> <meta charset="utf-8" /> <title ...
- INI配置文件分析小例子
随手写个解析INI配置字符串的小例子 带测试 #include <iostream> #include <map> #include <string> #inclu ...
- JavaScript小例子:复选框全选
JavaScript小例子:复选框全选 这只是一个小例子,很简单,但是这个功能还是很常用的: 实现后效果如图: JavaScript代码: <script type="text/jav ...
- 【zTree】 zTree使用的 小例子
使用zTree树不是第一次了 但是 还是翻阅着之前做的 对照着 使用起来比较方便 这里就把小例子列出来 总结一下使用步骤 这样方便下次使用起来方便一点 使用zTree树的步骤: 1.首先 在 ...
- js小例子(标签页)
运用js写的一个小例子,实现点击不同的标签出现不同的内容: <!DOCTYPE html> <html> <head> <meta chaset=" ...
- sbrk与brk的使用小例子
sbrk() 和 brk() - Unix的系统函数 sbrk()和brk() 系统的底层会维护一个位置,通过位置的移动完成内存的分配和回收.映射内存时 以一个内存页作为基本单位. void* ...
随机推荐
- eclipse 自动排版
自动排版: ctrl + i 同名变量高亮: shift+alt+ o 导包: shift+ctrl +o
- RTTI: dynamic_cast typeid
dynamic_cast:将基类类型的指针向派生类指针安全转换.多用于下行转换.上行转换时,和static_cast是一样的.C++类型转换看这里.而const_cast用来修改类型的const或vo ...
- tomcat源码分析(三)一次http请求的旅行-从Socket说起
p { margin-bottom: 0.25cm; line-height: 120% } tomcat源码分析(三)一次http请求的旅行 在http请求旅行之前,我们先来准备下我们所需要的工具. ...
- word域1
Description: 域是WORD中的一种特殊命令,它由花括号.域名(域代码)及选项开关构成.域代码类似于公式,域选项并关是特殊指令,在域中可触发特定的操作.在用WORD处理文档时若能巧妙应用域, ...
- html5悬浮球效果
自己想做一个自己的网站,觉得自适应的效果会好一点,但是放到手机端的话,菜单显示是个问题.所以自己试着写了一个悬浮球菜单的效果. 好了,上代码. 这里有四个文件要用: jqurey.js//因为基于jq ...
- SLES 10安装Oracle10gR2笔记
SLES 10安装Oracle10gR2笔记 一. 数据库安装 . 安装C/C++ Compiler gcc --version验证是否安装 . 验证Service Pack版本 SPident –v ...
- UVA 11464 偶数矩阵
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- C#的四种Timer介绍
一.Timer的几个类别 1.System.Threading.Timer 2.System.Timers.Timer 3.System.Windows.Forms.Timer 4.System.Wi ...
- 关于ES3、ES5、ES6以及ES7所有数组的方法(api)的总结
起因:工作用经常用到操作数组的方法,这里进行一下总结,我尽量以简洁的语言概括每个方法(api)的作用.如果您想快速定位,可以Control+F 然后搜相应的方法即可定位 :) ES3的数组方法 joi ...
- Date Picker和UITool Bar的使用
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Verdana } span.s1 { } span.s2 { background-colo ...