标签:
1 #ifndef _SOCKET_MANAGE_H_ 2 #define _SOCKET_MANAGE_H_ 3 4 #define MAX_SRV_NUM 100 5 #define DIGEST_LEN 20 6 #define MAX_BUF_SISE 4096 7 8 typedef struct 9 { 10 unsigned int uiPort; //端口 11 unsigned char ucArrIp[64]; //ip字符串 12 unsigned char ucArrPwd[64]; //Api口令 13 unsigned int uiEncPwdLen; //哈希过后的api口令长度 14 unsigned char ucArrEncPwd[64]; //哈希过后的api口令 15 } SrvInfo_St; 16 17 18 typedef struct 19 { 20 int uiSrvId; //该结构体中socket句柄对应的Server在SrvInfo_St结构体数组中的索引 21 int uiArrIndex; //本结构体在Handle_St结构体数组中的索引 22 int uiSocket; //真正的socket句柄 23 Sem sem; 24 } Handle_St; 25 26 27 #endif
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <Windows.h> 5 6 #include "SocketManage.h" 7 8 #pragma comment(lib, "Ws2_32.lib") 9 10 #define SML_BUFF_LEN 128 11 #define LRG_BUFF_LEN 4096 12 13 //------------------------------------------------------------------------------- 14 15 Mutex LOCK_Init; 16 Mutex LOCK_Handle; 17 18 int InitFlag = 0; //大于0代表已经初始化过 19 int TimeOut = 0; //超时时长 20 int ServerNum = 0; //签名服务器数量 21 22 int HandleMaxNum = 0; //最大需要创建的Socket句柄数 23 int HandleNum = 0; //已经创建的Socket句柄数 24 Handle_St* pHandle = NULL; //所有Socket句柄和服务器索引的对应 25 26 27 int FreeBgnIndex = 0; //从前面开始取,指向第一个可用的句柄 28 int FreeEndIndex = 0; //从后面开始放,指向即将放入句柄的索引,即最后一个可用句柄索引的下一个 29 30 int *pFreeIndex = NULL; //空闲Socket句柄索引缓存,值为Handle_St数组的索引 31 32 33 SrvInfo_St SrvInfos[MAX_SRV_NUM]; //存放服务器信息 34 35 // 上一个连接的索引 36 int LastConnectIndex = 0; 37 38 //------------------------------------------------------------------------------- 39 40 // 获取下一个会话索引 41 int GetNextHandleIndex() 42 { 43 int j = 0; 44 45 j = LastConnectIndex; 46 47 do 48 { 49 j = (j +1 )% HandleMaxNum; 50 51 LastConnectIndex = j; 52 53 return LastConnectIndex; 54 55 } while (j != LastConnectIndex); 56 57 return -1; 58 } 59 60 // 对所有签名服务器增加一个连接 61 int AllConnect() 62 { 63 64 int ret = 0; 65 int sockfd = 0; 66 int srvId = 0; 67 68 for(srvId = 0; srvId < ServerNum; srvId ++) 69 { 70 //需要考虑某Srv出错?? 71 ret = Socket_Conn((char *)SrvInfos[srvId].ucArrIp, SrvInfos[srvId].uiPort, TimeOut, &sockfd); 72 if ( 0 != ret) 73 return Err_Connect2Server; 74 else 75 { 76 //将新创建的句柄赋到句柄数组中 77 pHandle[HandleNum].uiSocket = sockfd; 78 79 pHandle[HandleNum].uiSrvId = srvId; 80 81 pHandle[HandleNum].uiArrIndex = HandleNum; 82 83 InitSem(&pHandle[HandleNum].sem); 84 85 //放入空闲句柄缓存 86 pFreeIndex[FreeEndIndex++] = HandleNum; 87 88 //指向下一个即将放入的句柄索引自增 89 HandleNum++; 90 91 } 92 93 } 94 95 return 0; 96 } 97 98 // 从pFreeIndex中取出空闲的Socket句柄索引 99 int GetFreeAvalSocket(Handle_St * pHdl) 100 { 101 int i = 0; 102 int ret = 0; 103 104 //index为空闲的Socket句柄的索引 105 int index = pFreeIndex[FreeBgnIndex]; 106 107 if(-1 != index) //有空闲句柄 108 { 109 pHdl->uiSocket = pHandle[index].uiSocket; 110 pHdl->uiSrvId = pHandle[index].uiSrvId; 111 112 pHdl->uiArrIndex = pHandle[index].uiArrIndex; 113 114 115 //取出来以后把原来的设为不可用 116 pFreeIndex[FreeBgnIndex] = -1; 117 118 //把可用的索引加一,指向下一个可用的 119 FreeBgnIndex ++; 120 121 //如果FreeBgnIndex指到头了以后重新改为指向第一个 122 if(FreeBgnIndex == HandleMaxNum) 123 FreeBgnIndex = 0; 124 } 125 else //没有空闲句柄 126 { 127 return -1; 128 } 129 130 return 0; 131 } 132 133 // 如果哪一台机器有可用的空闲句柄就用哪台机器 134 // 如果所有的机器都没有空闲句柄,就所有机器再加一次连接 135 int GetAvalSocket(Handle_St * pHdl) 136 { 137 int i = 0; 138 int ret = 0; 139 140 ret = GetFreeAvalSocket(pHdl); 141 142 if(0 != ret) //没有空闲的句柄 143 { 144 if(HandleNum >= HandleMaxNum) //句柄数已经达到最大数值 145 { 146 int UsableHandleIndex = GetNextHandleIndex(); 147 pHdl->uiArrIndex = UsableHandleIndex; 148 pHdl->uiSocket = pHandle[UsableHandleIndex].uiSocket; 149 pHdl->uiSrvId = pHandle[UsableHandleIndex].uiSrvId; 150 ret = 0; 151 152 } 153 else 154 { 155 ret = AllConnect(); 156 if(0 != ret) return ret; 157 158 ret = GetFreeAvalSocket(pHdl); 159 if(0 != ret) return ret; 160 161 } 162 163 } 164 165 return ret; 166 167 } 168 169 // 将不用的连接重新放入对应Srv的空闲句柄缓存中 170 int FreeAvalSocket(Handle_St *pHdl) 171 { 172 if(FreeEndIndex == HandleMaxNum) 173 FreeEndIndex = 0; 174 175 pFreeIndex[FreeEndIndex] = pHdl->uiArrIndex; 176 177 FreeEndIndex++; 178 179 180 pHdl->uiArrIndex = -1; 181 pHdl->uiSocket = -1; 182 pHdl->uiSrvId = -1; 183 184 return 0; 185 } 186 187 // 对于已经不可用的连接进行重连 188 int ReConnect(Handle_St *pHdl) 189 { 190 int ret = 0; 191 int sockfd = 0; 192 193 int srvId = 0; 194 195 MutexLock(&LOCK_Handle); 196 197 srvId = pHdl->uiSrvId; 198 199 close(pHdl->uiSocket); 200 201 ret = Socket_Conn((char *)SrvInfos[srvId].ucArrIp, SrvInfos[srvId].uiPort, TimeOut, &sockfd); 202 if(0 == ret) 203 pHdl->uiSocket = sockfd; 204 205 MutexUnLock(&LOCK_Handle); 206 return ret; 207 208 } 209 210 int CheckSockFd(int sockFd) 211 { 212 if(0 > sockFd || sockFd >= HandleMaxNum) 213 return Err_InvalidData; 214 else 215 return 0; 216 } 217 218 //------------------------------------------------------------------------------- 219 220 int InitMoudle() 221 { 222 InitMutex(&LOCK_Init); 223 InitMutex(&LOCK_Handle); 224 225 return 0; 226 } 227 228 int InitServer(const char *pucIpStr, const char *puiPortStr, const int uiTimeOut, 229 const char *pucApiPasswdStr, const int uiMaxConnection) 230 { 231 int ret = 0; 232 int i = 0; 233 int j = 0; 234 int sockfd = 0; 235 236 MutexLock(&LOCK_Init); 237 238 if(0 < InitFlag) 239 { 240 MutexUnLock(&LOCK_Init); 241 return 0; 242 } 243 244 TimeOut = uiTimeOut /1000; 245 memset(SrvInfos, 0x00, MAX_SRV_NUM * sizeof(SrvInfo_St)); 246 247 //------------------------------------------------------------------------------- 248 //将IP字符串、端口字符串、Pwd字符串转换到SrvInfos数组中保存 249 //ret = SrvInfoFmt(pucIpStr, strlen(pucIpStr), puiPortStr, strlen(puiPortStr), 250 // pucApiPasswdStr, strlen(pucApiPasswdStr), SrvInfos, &ServerNum); 251 //if(0 != ret) return Err_InvalidData; 252 253 ServerNum = 1; 254 SrvInfos[0].uiPort = atoi(puiPortStr); 255 memcpy(SrvInfos[0].ucArrIp, pucIpStr, strlen(pucIpStr)); 256 257 //------------------------------------------------------------------------------- 258 259 //计算所有签名服务器最大连接数,一定为Srv数目的倍数 260 if(0 != uiMaxConnection % ServerNum) 261 HandleMaxNum = uiMaxConnection + ServerNum - uiMaxConnection % ServerNum; 262 else 263 HandleMaxNum = uiMaxConnection; 264 265 //将上一次连接的索引初始化为最大连接数减1。 266 LastConnectIndex = HandleMaxNum - 1; 267 268 //空闲句柄索引缓存分配 269 pFreeIndex = (int *)calloc(HandleMaxNum, sizeof(int)); 270 271 //所有句柄缓存初始化 272 pHandle = (Handle_St*)calloc(HandleMaxNum, sizeof(Handle_St)); 273 274 for(i = 0 ;i < HandleMaxNum; i ++) 275 { 276 pHandle[i].uiSocket = -1; 277 pHandle[i].uiSrvId = -1; 278 pHandle[i].uiArrIndex = -1; 279 280 pFreeIndex[i] = -1; 281 282 } 283 284 //每个Srv连接一次,连接后将句柄保存在数组中 285 //需要考虑某Srv出错?? 286 ret = AllConnect(); 287 288 InitFlag++; 289 290 MutexUnLock(&LOCK_Init); 291 292 293 return ret; 294 } 295 296 297 int GetConnection(int *psockFd) 298 { 299 Handle_St Handle; 300 301 MutexLock(&LOCK_Handle); 302 303 memset(&Handle, 0x00, sizeof(Handle_St)); 304 305 GetAvalSocket(&Handle); 306 307 *psockFd = Handle.uiArrIndex; 308 309 MutexUnLock(&LOCK_Handle); 310 311 return 0; 312 } 313 314 int CloseConnection(int sockFd) 315 { 316 Handle_St Handle; 317 318 if(0 != CheckSockFd(sockFd)) 319 return Err_InvalidData; 320 321 MutexLock(&LOCK_Handle); 322 323 Handle.uiArrIndex = sockFd; 324 Handle.uiSocket = pHandle[sockFd].uiSocket; 325 Handle.uiSrvId = pHandle[sockFd].uiSrvId; 326 327 FreeAvalSocket(&Handle); 328 329 MutexUnLock(&LOCK_Handle); 330 331 return 0; 332 }
标签:
原文地址:http://www.cnblogs.com/ggxxjj123/p/4528362.html