tupApi.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "includes.h"
  2. void tupParaSet(TUPSEND_DEF *para, T_UINT16 port, MY_SOCK_CB *callback,T_UINT16 stacksize){
  3. para->port=port;
  4. para->tupRecvCallBack=callback;
  5. para->stacksize=stacksize;
  6. }
  7. void trySendTup(T_UINT8 *data, T_UINT16 len, TUP_ENUM tup, TUPSEND_DEF *para){
  8. T_INT32 ret;
  9. if(para->fd<=0) return;
  10. if(TUP_TCP==para->tupType) ret=nwy_socket_send(para->fd,data,len,0);
  11. else ret=nwy_socket_sendto(para->fd,data,len,0, &para->sockAddr, sizeof(struct sockaddr_in));
  12. if(ret<0) wlog_info("tup[%d]:%d send failed", para->fd,len);
  13. else wlog_info("tup[%d]:%d send ok",para->fd,len);
  14. }
  15. void userCloseSocket(T_INT32 *fd){
  16. if(*fd<=0) return;
  17. wlog_info("SockClose:%d",*fd);
  18. nwy_socket_close(*fd);
  19. *fd=-1;
  20. }
  21. void showTupEventInfo(const char *name, T_UINT32 id,TUPSEND_DEF *para, char needShutWhenSerShut){
  22. // if(para->ptimer_t!=NULL){//有回调响应后清除定时器
  23. // wlog_info("[%s]timerStop",name);
  24. // LSAPI_OSI_TimerStop(para->ptimer_t);
  25. // para->ptimer_t=NULL;
  26. // }
  27. switch(id){
  28. case TUP_EVENT_SOCK_LINK_RECV: wlog_info("[%d %s]:recv data ok",id,name);break;
  29. case TUP_EVENT_SOCK_LINK_SERVER_SHUT:
  30. para->tupStatus=CNNT_CLOSED;
  31. if(needShutWhenSerShut==0) userCloseSocket(&para->fd);
  32. else wlog_info("[%d %s dly shut fd",id,name);
  33. wlog_info("[%d %s]:server shut",id,name);
  34. break;
  35. case TUP_EVENT_SOCK_LINK_ERR: para->tupStatus=CNNT_ERROR;userCloseSocket(&para->fd);wlog_info("[%d %s]:link err",id,name);break;
  36. case TUP_EVENT_SOCK_LINK_OK:para->tupStatus=CNNT_OK;wlog_info("[%d %s]:link ok",id,name);break;
  37. case TUP_EVENT_SOCK_LINK_CLIENT_SHUT: para->tupStatus=CNNT_CLOSED;userCloseSocket(&para->fd);wlog_info("[%d %s]:client shut",id,name);break;
  38. // case LSAPI_SOCK_TCPIP_SOCKET_SEND_RSP: wlog_info("[%d %s]:send data ok",id,name);break;
  39. case TUP_EVENT_SOCK_LINK_TIMEOUT: para->tupStatus=CNNT_TOUT;userCloseSocket(&para->fd);wlog_info("[%d %s]:link tout",id,name);break;
  40. default:wlog_info("%d %s]:ignore",id,name);break;
  41. }
  42. WakeupNow(name);
  43. }
  44. void sockTimerOutCallback(void *param){
  45. // TUPSEND_DEF *para=(TUPSEND_DEF *)param;
  46. // wlog_info("sockTimerOutCallback enter");
  47. // LSAPI_OSI_TimerStop(para->ptimer_t);
  48. // userCloseSocket(&para->fd);
  49. // para->errno=3;//连接超时错误3
  50. // threadPostEvent(nwy_get_current_thread(),USER_EVENT_EXIT);
  51. }
  52. void sockEntry(void *param){
  53. TUPSEND_DEF *para=(TUPSEND_DEF *)param;
  54. T_INT32 sockfd;
  55. T_INT32 type,tup;
  56. char recbuf[1024];
  57. int g_keepalive = 0;
  58. wlog_info("[NewThread:sockEntry]%x",nwy_get_current_thread());
  59. if(TUP_TCP==para->tupType){
  60. type=SOCK_STREAM;
  61. tup=IPPROTO_TCP;
  62. }else{
  63. type=SOCK_DGRAM;
  64. tup=IPPROTO_UDP;
  65. }
  66. // sockfd = LSAPI_SOCK_Create(LSAPI_SOCK_TCPIP_AF_INET, type, 0, para->tupRecvCallBack,(uint32_t)para);
  67. sockfd = nwy_socket_open(AF_INET,type,tup);
  68. if(sockfd<0){
  69. wlog_info("sockfd create err=%d",nwy_socket_errno());
  70. para->errno=1;//错误1
  71. nwy_exit_thread();
  72. return;
  73. }
  74. ip_addr_t addr;
  75. para->fd=sockfd;
  76. wlog_info("tup info:%d,%s:%d", sockfd,para->saddr, para->port);
  77. struct sockaddr_in *serveraddr=&para->sockAddr;
  78. serveraddr->sin_family = AF_INET;
  79. serveraddr->sin_port = htons(para->port);
  80. if(0==ipaddr_aton(para->saddr, &addr)){
  81. wlog_error("ipaddr_aton failed");
  82. userCloseSocket(&sockfd);
  83. para->fd=0;
  84. para->errno=2;//错误2
  85. userExitThread("sockEntry");
  86. return;
  87. }
  88. inet_addr_from_ip4addr(&serveraddr->sin_addr, ip_2_ip4(&addr));
  89. nwy_socket_setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&g_keepalive, sizeof(g_keepalive));
  90. if(0!=nwy_socket_set_nonblock(sockfd)){
  91. wlog_error("set_nonblock err");
  92. userCloseSocket(&sockfd);
  93. para->fd=0;
  94. para->errno=2;//错误2
  95. userExitThread("sockEntry");
  96. return;
  97. }
  98. //if(0 != nwy_socket_connect(sockfd, serveraddr,sizeof(para->sockAddr))){
  99. // wlog_error("sockfd connect err");
  100. // userCloseSocket(&sockfd);
  101. // para->fd=0;
  102. // para->errno=2;//错误2
  103. // userExitThread("sockEntry");
  104. // return;
  105. //}
  106. //创建一个定时器用于连接超时
  107. //para->ptimer_t=LSAPI_OSI_TimerCreate(nwy_get_current_thread(), sockTimerOutCallback, param);
  108. //if(NULL != para->ptimer_t) LSAPI_OSI_TimerStart(para->ptimer_t, 10000);//设置为超时10秒
  109. wlog_info("open fd:%d",sockfd);
  110. //做成事件响应型
  111. nwy_osiEvent_t tevent={0};
  112. int ret=-1,errno,cntstatus=0;
  113. int64_t timeout=nwy_get_ms();
  114. tevent.param3=para;
  115. fd_set rd_fd,ex_fd;
  116. struct timeval tv;//不能用临时变量
  117. tv.tv_sec=10;
  118. tv.tv_usec=0;
  119. for(;;){
  120. //检测是否连接超时
  121. if(cntstatus==0){//未连接成功时操作
  122. if(((nwy_get_ms()-timeout))>=10000){
  123. //超时未连接成功
  124. cntstatus=-1;
  125. tevent.id=TUP_EVENT_SOCK_LINK_TIMEOUT;
  126. para->tupRecvCallBack((void *)&tevent);
  127. }
  128. //检测是否connect成功
  129. if(ret!=0){
  130. ret=nwy_socket_connect(sockfd, serveraddr,sizeof(para->sockAddr));
  131. }
  132. if(ret!=0){//connet未成功,需要进一步检测
  133. errno=nwy_socket_errno();
  134. if(EALREADY == errno || EISCONN == errno){
  135. //连接成功
  136. cntstatus=1;
  137. }else if(EINPROGRESS != errno){
  138. //连接失败
  139. cntstatus=-2;
  140. tevent.id=TUP_EVENT_SOCK_LINK_ERR;
  141. para->tupRecvCallBack((void *)&tevent);
  142. }
  143. nwy_sleep(100);
  144. }else cntstatus=1;
  145. if(cntstatus==1){
  146. tevent.id=TUP_EVENT_SOCK_LINK_OK;
  147. para->tupRecvCallBack((void *)&tevent);
  148. }
  149. }else if(cntstatus==1){//select操作
  150. FD_ZERO(&rd_fd);FD_ZERO(&ex_fd);
  151. FD_SET(sockfd,&rd_fd);FD_SET(sockfd, &ex_fd);
  152. int result=nwy_socket_select(sockfd+1,&rd_fd,NULL,&ex_fd,&tv);
  153. if(result<0){//select 失败
  154. cntstatus=-3;
  155. tevent.id=TUP_EVENT_SOCK_LINK_ERR;
  156. para->tupRecvCallBack((void *)&tevent);
  157. }else if(result==0){//select 超时
  158. //没有数据可读,继续select
  159. }else{//select 成功
  160. if(FD_ISSET(sockfd, &rd_fd)){//有数据可读
  161. FD_CLR(sockfd, &rd_fd);
  162. int len;
  163. if(tup==IPPROTO_TCP) len=nwy_socket_recv(sockfd, recbuf, sizeof(recbuf),0);
  164. else{
  165. int tlen=sizeof(para->sockAddr);
  166. len=nwy_socket_recvfrom(sockfd, recbuf, sizeof(recbuf), 0, serveraddr,&tlen);
  167. }
  168. if(len==0){
  169. cntstatus=-4;
  170. tevent.id=TUP_EVENT_SOCK_LINK_SERVER_SHUT;
  171. para->tupRecvCallBack((void *)&tevent);
  172. }else if(len>0){
  173. tevent.id=TUP_EVENT_SOCK_LINK_RECV;
  174. tevent.param1=recbuf;
  175. tevent.param2=len;
  176. para->tupRecvCallBack((void *)&tevent);
  177. }else{
  178. cntstatus=-5;
  179. tevent.id=TUP_EVENT_SOCK_LINK_CLIENT_SHUT;
  180. para->tupRecvCallBack((void *)&tevent);
  181. }
  182. }
  183. if(FD_ISSET(sockfd, &ex_fd)){//异常
  184. tevent.id=TUP_EVENT_SOCK_LINK_ERR;
  185. cntstatus=-6;
  186. para->tupRecvCallBack((void *)&tevent);
  187. FD_CLR(sockfd, &rd_fd);
  188. }
  189. }
  190. }else{//退出线程
  191. nwy_sleep(50);
  192. userCloseSocket(&para->fd);
  193. userExitThread("sockEntry");
  194. }
  195. }
  196. }
  197. TUP_CONNECT_ENUM tryConnectTup(T_INT8 *seraddr, TUP_ENUM tup,TUPSEND_DEF *para){
  198. //必须使用线程来创建连接再waitevent
  199. para->saddr=seraddr;
  200. para->tupType=tup;
  201. para->errno=0;
  202. para->tupStatus=CNNT_BUSY;
  203. para->fd=0;
  204. if(NULL==nwy_create_thread("sockCreate", sockEntry,(void *)para,NWY_OSI_PRIORITY_NORMAL,para->stacksize,4)){
  205. wlog_error("tryConnectTup thread create error for %s",seraddr);
  206. return TUP_STATUS_FALSE;
  207. }
  208. return TUP_STATUS_WAIT;
  209. }