#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef WIN32
#include <WinSock2.h>
#include <Windows.h>
#endif
#include "tcp_session.h"
#define MAX_SESSION_NUM 6000
#define my_malloc malloc
#define my_free free
#define MAX_RECV_BUFFER 8096
struct {
struct session* online_session;
struct session* cache_mem;
struct session* free_list;
char recv_buffer[MAX_RECV_BUFFER];
int readed; // 当前已经从socket里面读取的数据;
int has_removed;
int prot_mode; // 0 表示二进制协议,size + 数据的模式
// 1,表示文本协议,以回车换行来分解收到的数据为一个包
}session_manager;
static struct session* cache_alloc() {
struct session* s = NULL;
if (session_manager.free_list != NULL) {
s = session_manager.free_list;
session_manager.free_list = s->next;
}
else { // 调用系统的函数 malloc
s = my_malloc(sizeof(struct session));
}
memset(s, 0, sizeof(struct session));
return s;
}
static void cache_free(struct session* s) {
// 判断一下,是从cache分配出去的,还是从系统my_malloc分配出去的?
if (s >= session_manager.cache_mem && s < session_manager.cache_mem + MAX_SESSION_NUM) {
s->next = session_manager.free_list;
session_manager.free_list = s;
}
else {
my_free(s);
}
//
}
void init_session_manager() {
memset(&session_manager, 0, sizeof(session_manager));
// 将6000个session一次分配出来。
session_manager.cache_mem = (struct session*)my_malloc(MAX_SESSION_NUM * sizeof(struct session));
memset(session_manager.cache_mem, 0, MAX_SESSION_NUM * sizeof(struct session));
// end
for (int i = 0; i < MAX_SESSION_NUM; i++) {
session_manager.cache_mem[i].next = session_manager.free_list;
session_manager.free_list = &session_manager.cache_mem[i];
}
}
void exit_session_manager() {
}
struct session* save_session(int c_sock, char* ip, int port) {
struct session* s = cache_alloc();
s->c_sock = c_sock;
s->c_port = port;
int len = strlen(ip);
if (len >= 32) {
len = 31;
}
strncpy(s->c_ip, ip, len);
s->c_ip[len] = 0;
s->next = session_manager.online_session;
session_manager.online_session = s;
return s;
}
void foreach_online_session(int(*callback)(struct session* s, void* p), void*p) {
if (callback == NULL) {
return;
}
struct session* walk = session_manager.online_session;
while (walk) {
if (walk->removed == 1) {
walk = walk->next;
continue;
}
if (callback(walk, p)) {
return;
}
walk = walk->next;
}
}
void close_session(struct session* s) {
s->removed = 1;
session_manager.has_removed = 1;
printf("client %s:%d exit\n", s->c_ip, s->c_port);
}
static void text_process_package(struct session* s) {
}
static void bin_process_package(struct session* s) {
if (session_manager.readed < 4) { // 保留好数据,return
return;
}
// 二进制分包的规则
int* pack_size = (int*)session_manager.recv_buffer;
int pack_len = (*pack_size);
if (pack_len > MAX_RECV_BUFFER) {
goto pack_failed;
}
// end
// 包没有收完
int total = 0; // 总共处理掉的包的数据大小
while ((session_manager.readed - total) >= pack_len) {
// 包收完了,结合玩家进行处理。
// end
// 移动到下一个包进行处理
total += pack_len;
if (session_manager.readed - total < 4) {
if (session_manager.readed > total) {
memmove(session_manager.recv_buffer, session_manager.recv_buffer + total, (session_manager.readed - total));
}
session_manager.readed -= total;
return;
}
pack_size = (int*)(session_manager.recv_buffer + total);
pack_len = (*pack_size);
if (pack_len > MAX_RECV_BUFFER) {
goto pack_failed;
}
if ((session_manager.readed - total) < pack_len) {
memmove(session_manager.recv_buffer, session_manager.recv_buffer + total, (session_manager.readed - total));
session_manager.readed -= total;
return;
}
// end
}
return;
pack_failed:
close_session(s);
}
// 处理我们的socket数据
void session_on_recv(struct session* s) {
int readed = recv(s->c_sock, session_manager.recv_buffer + session_manager.readed, MAX_RECV_BUFFER - session_manager.readed, 0);
if (readed <= 0) { // 客服端已经关闭了socket
close_session(s);
return;
}
session_manager.readed += readed;
if (session_manager.prot_mode == 0) {
bin_process_package(s);
}
else {
text_process_package(s);
}
}
void clear_offline_session() {
if (session_manager.has_removed == 0) {
return;
}
struct session** walk = &session_manager.online_session;
while (*walk) {
struct session* s = (*walk);
if (s->removed) {
*walk = s->next;
s->next = NULL;
closesocket(s->c_sock);
s->c_sock = 0;
// 释放session
cache_free(s);
}
else {
walk = &(*walk)->next;
}
}
session_manager.has_removed = 0;
}
没有合适的资源?快使用搜索试试~ 我知道了~
c++Socket编程自己写的
共51个文件
tlog:12个
c:6个
h:4个
需积分: 36 19 下载量 126 浏览量
2018-06-01
18:08:16
上传
评论 4
收藏 17.41MB ZIP 举报
温馨提示
c++Socket编程,是使用TCP写的,有客户端和服务器,给刚刚学习socket的同学举个例子
资源推荐
资源详情
资源评论
收起资源包目录
c_tcp_demo.zip (51个子文件)
c_tcp_demo
tcp_client
proj.win32
tcp_client
tcp_client.vcxproj 4KB
Debug
tcp_client.log 123B
vc120.pdb 92KB
tcp_client.tlog
tcp_client.lastbuildstate 197B
CL.write.1.tlog 684B
link.command.1.tlog 1KB
CL.read.1.tlog 19KB
link.write.1.tlog 702B
cl.command.1.tlog 682B
link.read.1.tlog 3KB
vc120.idb 211KB
main.obj 25KB
tcp_client.vcxproj.filters 421B
tcp_client.sdf 27.88MB
Debug
tcp_client.ilk 242KB
tcp_client.pdb 620KB
tcp_client.exe 31KB
tcp_client.sln 976B
tcp_client.v12.suo 19KB
src
main.c 999B
tcp_server
proj.win32
tcp_server.v12.suo 32KB
tcp_server.sdf 28.5MB
tcp_server.sln 976B
tcp_server
Debug
vc120.pdb 100KB
tcp_listener.obj 31KB
tcp_server.log 130B
vc120.idb 371KB
tcp_session.obj 32KB
main.obj 4KB
tcp_server.tlog
tcp_server.lastbuildstate 197B
CL.write.1.tlog 9KB
link.command.1.tlog 2KB
CL.read.1.tlog 79KB
link.write.1.tlog 1KB
cl.command.1.tlog 4KB
link.read.1.tlog 3KB
tcp_server.vcxproj 4KB
tcp_server.vcxproj.filters 1KB
tcp_server.vcxproj.user 165B
Debug
tcp_server.ilk 292KB
tcp_server.exe 35KB
tcp_server.pdb 692KB
src
class_code
tcp_session.c 5KB
tcp_listener.h 117B
tcp_session.h 605B
tcp_listener.c 3KB
socket_io
tcp_session.c 4KB
tcp_listener.h 116B
tcp_session.h 802B
tcp_listener.c 3KB
main.c 218B
共 51 条
- 1
资源评论
qq_15623157
- 粉丝: 1
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- Java 算法实现代码集.zip
- JSP高校教务排课管理系统源码.zip
- JSP二手自行车在线销售商城平台系统源码.zip
- JSP二手自行车销售商城源码.zip
- JSP宠物店管理系统源码.zip
- 基于动态阈值图像分割方法和与全局阈值相结合的分割方法.zip
- 基于protel99se(原理图库+封装库)电路设计硬件PCB设计protel库合集protel封装大全(近3000个).zip
- python-leetcode面试题解之第157题用Read4读取N个字符-题解.zip
- python-leetcode面试题解之第156题上下翻转二叉树-题解.zip
- python-leetcode面试题解之第155题最小栈-题解.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功