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 小例子的更多相关文章

  1. springmvc入门的第一个小例子

    今天我们探讨一下springmvc,由于是初学,所以简单的了解一下 springmvc的流程,后续会持续更新... 由一个小例子来简单的了解一下 springmvc springmvc是spring框 ...

  2. java即时通信小例子

    学习java一段时间了,今天写来一个即时通信的小例子练手在其过程中也学到了一些知识拿出来和大家分享,请路过的各位大神多多赐教... 好了下面讲一下基本的思路: 首先,编写服务器端的程序,简单点说吧就是 ...

  3. Runtime的几个小例子(含Demo)

    一.什么是runtime(也就是所谓的“运行时”,因为是在运行时实现的.)           1.runtime是一套底层的c语言API(包括很多强大实用的c语言类型,c语言函数);  [runti ...

  4. bootstrap 模态 modal 小例子

    bootstrap 模态 modal  小例子 <html> <head> <meta charset="utf-8" /> <title ...

  5. INI配置文件分析小例子

    随手写个解析INI配置字符串的小例子 带测试 #include <iostream> #include <map> #include <string> #inclu ...

  6. JavaScript小例子:复选框全选

    JavaScript小例子:复选框全选 这只是一个小例子,很简单,但是这个功能还是很常用的: 实现后效果如图: JavaScript代码: <script type="text/jav ...

  7. 【zTree】 zTree使用的 小例子

    使用zTree树不是第一次了  但是 还是翻阅着之前做的 对照着 使用起来比较方便  这里就把小例子列出来   总结一下使用步骤 这样方便下次使用起来方便一点 使用zTree树的步骤: 1.首先  在 ...

  8. js小例子(标签页)

    运用js写的一个小例子,实现点击不同的标签出现不同的内容: <!DOCTYPE html> <html> <head> <meta chaset=" ...

  9. sbrk与brk的使用小例子

    sbrk() 和 brk() - Unix的系统函数   sbrk()和brk() 系统的底层会维护一个位置,通过位置的移动完成内存的分配和回收.映射内存时 以一个内存页作为基本单位.   void* ...

随机推荐

  1. 在iOS中使用OpenSSL的Public Key 进行加密

    这几天一直潜心于iOS开发,刚好把遇到的问题都记录一下.这次遇到的问题就是如果根据得到的Public Key在iOS 客户端对用户名和密码进行加密. Public Key如下: -----BEGIN ...

  2. 菜鸟学Android编程——简单计算器《一》

    菜鸟瞎搞,高手莫进 本人菜鸟一枚,最近在学Android编程,网上看了一些视频教程,于是想着平时手机上的计算器应该很简单,自己何不尝试着做一个呢? 于是就冒冒失失的开撸了. 简单计算器嘛,功能当然很少 ...

  3. 学习日志 - Openwrt安装python然后wallproxy

    前提: - 先要把U盘插入路由器的usb口,大多数情况Openwrt都会自动挂载的吧,尽量找当前年或前一年的固件.ssh进路由器,可以看到/mnt/sda1 -  让路由器联网,因为需要从网络上下载安 ...

  4. 关于sqlserver 2008 无法远程连接的问题

    Sqlserver 2008 无法远程连接,原因无非如下: 1. Sql未配置为允许TCP/IP登录: 2. 防火墙未允许端口1433(或者其他在SQL配置中指定的端口): 3. 命名实例导致的无法连 ...

  5. NPOI 教程 - 2.1单元格合并

    来源:http://liyingchun343333.blog.163.com/blog/static/3579731620091018212990/ 合并单元格在制作表格时很有用,比如说表格的标题就 ...

  6. Ubuntu 16.04 LTS 安装 Nginx/PHP 5.6/MySQL 5.7 (LNMP) 与Laravel

    Ubuntu 16.04 LTS 安装 Nginx/PHP 5.6/MySQL 5.7 (LNMP) 与Laravel 1.MySQL安装[安装 MariaDB]MariaDB是MySQL的一个分支首 ...

  7. Python,Jupyter Notebook,IPython快速安装教程

    0.安装环境 Windows10,Python3.5.1,IPython,jupyter notebook,and other functionality 官方安装文档Linux版3.x 官方安装文档 ...

  8. Oculus中OVRPlayerController飞行视角的制作

    最近项目上的事,忙的不可开交.忙里偷闲,记录下Oculus飞行视角的制作 师兄给我的要求是,带上Oculus,通过remote和头盔操作,可以完成飞行我的解决办法:1.消除重力的影响,如同在真空中,就 ...

  9. 什么是js和js的基本语法

    时间:2016年12月15日 先讲讲基础语法: 大部分是来操作表单: js动态效果和数据交互(ajax?) js也有自己的API js大部分的DOM操作都是针对input的. 案例学习,对注册页面的简 ...

  10. iOS获取当前时间

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; // ----------设置你想要的格式,hh与HH的区别:分别表示12小时 ...