udp编译模型-- 基于tcp上二次开发
<DIV>#include <string.h><BR>#include <stdio.h><BR>#include <stdlib.h><BR>#include <winsock2.h></DIV><DIV><BR>#include "msinc.h"<BR>#include "mssoc.h"<BR>#include "mslog.h"<BR>#include "mssim.h"</DIV>
<DIV>#define sm_set_core_flag()<BR>#define sm_set_app_flag()</DIV>
<DIV>/* -------------------------------------------------------------------------- <BR> * 模块内部变量声明。<BR> * ----------------------------------------------------------------------- */<BR>typedef struct _soc_session_t {<BR> int used;<BR> int handle;<BR> SOCKET socket;<BR> enum {TCP_CONNECTING, TCP_CONNECTED, TCP_WAIT_CLOSE} tcp_state;<BR> enum {UDP_CONNECTING, UDP_CONNECTED, UDP_WAIT_CLOSE} udp_state;<BR> enum {BLOCK_WRITE, CAN_WRITE} write_pipe;<BR> enum {BLOCK_READ, CAN_READ} read_pipe;<BR> //void (*hook)(int handler, int state);<BR> ms_sockaddr addr;<BR> ms_get_host_cb_t get_host_cb;<BR> ms_soc_cb_t soc_cb;<BR>} soc_session_t;<BR>#define MS_SOC_MAX_NUM (3)<BR>/**<BR> * 并发TCP会话队列。<BR> */<BR>static soc_session_t sessions;</DIV>
<DIV>/*<BR> * 队列定时器初始化标志。<BR> */<BR>static int init_timer = 0;</DIV>
<DIV>/*<BR> * 定时器的ID号。<BR> */<BR>static int itemer_id = -1;</DIV>
<DIV>/*<BR> * 系统忙标志。<BR> */<BR>static int busy = 0;</DIV>
<DIV>/* -------------------------------------------------------------------------- <BR> * 模块内部函数声明。<BR> * ----------------------------------------------------------------------- */</DIV>
<DIV>/**<BR> * TCP队列处理定时器函数。<BR> */<BR>static void proc_sessions(int tid, int p);</DIV>
<DIV>/**<BR> * 处理会话。<BR> */<BR>static void proc_session(soc_session_t* session);</DIV>
<DIV>/**<BR> * tcp模块的初始化函数。<BR> */<BR>static int soc_mod_init_func(void);</DIV>
<DIV>/**<BR> * tcp模块的清理函数。<BR> */<BR>static int soc_mod_fina_func(void);</DIV>
<DIV>static int soc_mod_init_func(void)<BR>{ <BR> WSADATA ws;<BR> int ret = -1;</DIV>
<DIV> ret = WSAStartup(MAKEWORD(1, 1), &ws);<BR> if (ret != 0)<BR> return -1;<BR> else <BR> {<BR> itemer_id = -1;<BR> init_timer = 0; <BR> }</DIV>
<DIV> return 0;<BR>}</DIV>
<DIV>static int soc_mod_fina_func(void)<BR>{<BR> WSACleanup();</DIV>
<DIV> if (init_timer && itemer_id >= 0)<BR> {<BR> ms_delete_timer((uint16)itemer_id);<BR> itemer_id = -1;<BR> init_timer = 0;<BR> }<BR> <BR> return 0;<BR>}</DIV>
<DIV>void proc_session(soc_session_t* session) {<BR> int v;<BR> fd_set fdrds, fdwrs;<BR> struct timeval timeout = {0, 0};</DIV>
<DIV> if (!init_timer)<BR> return;<BR> <BR> switch(session->tcp_state) <BR> {<BR> case TCP_CONNECTING:<BR> FD_ZERO(&fdwrs);<BR> FD_SET(session->socket, &fdwrs);<BR> <BR> if ((v = select(1, NULL, &fdwrs, NULL, &timeout)) == SOCKET_ERROR) <BR> {<BR> if (session->soc_cb)<BR> {<BR> sm_set_app_flag();<BR> session->soc_cb(session->handle, MS_SOCEVT_CONNECT_FAILED);<BR> sm_set_core_flag();<BR> }<BR> return;<BR> }<BR> if (v > 0 && FD_ISSET(session->socket, &fdwrs)) <BR> {<BR> session->tcp_state = TCP_CONNECTED;<BR> session->read_pipe = CAN_READ;<BR> session->write_pipe = CAN_WRITE;<BR> if (session->soc_cb)<BR> {<BR> sm_set_app_flag();<BR> session->soc_cb(session->handle, MS_SOCEVT_CONNECT);<BR> sm_set_core_flag();<BR> }<BR> }<BR> break;<BR> case TCP_CONNECTED:<BR> if (session->write_pipe == BLOCK_WRITE)<BR> {<BR> FD_ZERO(&fdwrs);<BR> FD_SET(session->socket, &fdwrs);<BR> <BR> if ((v = select(1, NULL, &fdwrs, NULL, &timeout)) == SOCKET_ERROR) <BR> {<BR> if (session->soc_cb)<BR> {<BR> sm_set_app_flag();<BR> session->soc_cb(session->handle, MS_SOCEVT_CONNECT_FAILED);<BR> sm_set_core_flag();<BR> }<BR> return;<BR> }<BR> if (v > 0 && FD_ISSET(session->socket, &fdwrs)) <BR> {<BR> session->write_pipe = CAN_WRITE;<BR> if (session->soc_cb)<BR> {<BR> sm_set_app_flag();<BR> session->soc_cb(session->handle, MS_SOCEVT_WRITE);<BR> sm_set_core_flag();<BR> }<BR> }<BR> } <BR> <BR> FD_ZERO(&fdrds);<BR> FD_SET(session->socket, &fdrds);<BR> if ((v = select(1, &fdrds, NULL, NULL, &timeout)) == SOCKET_ERROR) <BR> {<BR> if (session->soc_cb)<BR> {<BR> sm_set_app_flag();<BR> session->soc_cb(session->handle, MS_SOCEVT_CONNECT_FAILED);<BR> sm_set_core_flag();<BR> }<BR> return;<BR> }<BR> if ((v > 0) && FD_ISSET(session->socket, &fdrds)) <BR> {<BR> session->read_pipe = CAN_READ;<BR> if (session->soc_cb)<BR> {<BR> sm_set_app_flag();<BR> session->soc_cb(session->handle, MS_SOCEVT_READ);<BR> sm_set_core_flag();<BR> }<BR> }<BR> <BR> break;<BR> case TCP_WAIT_CLOSE:<BR> if (session->soc_cb)<BR> {<BR> sm_set_app_flag();<BR> session->soc_cb(session->handle, MS_SOCEVT_CLOSE);<BR> sm_set_core_flag();<BR> }<BR> session->used = FALSE;<BR> session->soc_cb = NULL;<BR> break;<BR> } <BR>}</DIV>
<DIV><BR>void proc_sessions(int tid, int p) {<BR> int i;</DIV>
<DIV> if (busy)<BR> return ;</DIV>
<DIV> busy = TRUE;</DIV>
<DIV> for (i = 0; i < MS_SOC_MAX_NUM; i++) {<BR> if (sessions.used) {<BR> proc_session(sessions + i);<BR> }<BR> }</DIV>
<DIV> busy = FALSE;<BR>}</DIV>
<DIV><BR>/************************************************************************************/<BR>//mssoc.h</DIV>
<DIV>int bearer_mode;<BR>int bearer_status;<BR>ms_bearer_cb_t bearer_cb;</DIV>
<DIV>int ms_soc_init()<BR>{<BR> soc_mod_init_func();</DIV>
<DIV> if (bearer_status)<BR> return -1;<BR> if (!init_timer) <BR> {<BR> <BR> memset(&sessions, 0, sizeof(sessions));<BR> //ms_quick_timer(200, 0, proc_sessions, 1);<BR> ms_quick_timer(1000,0, proc_sessions,1);<BR> init_timer = TRUE;<BR> }</DIV>
<DIV> return 0;<BR>}</DIV>
<DIV>int ms_soc_finalize()<BR>{<BR> if (bearer_status)<BR> ms_bearer_close();</DIV>
<DIV> soc_mod_fina_func();<BR> return 0;<BR>}</DIV>
<DIV>static void bearer_timer_cb(int tid, int p)<BR>{<BR> if (bearer_cb)<BR> {<BR> if (!p)<BR> { <BR> bearer_status = 1;<BR> bearer_cb(MS_BEARER_OK);<BR> }<BR> else<BR> {<BR> bearer_status = 0;<BR> //bearer_cb(MS_BEARER_FAILED);<BR> }<BR> }<BR>}<BR>int ms_bearer_open(int mode, void * cb)<BR>{<BR> if (!bearer_status)<BR> {<BR> ms_quick_timer(2000, 0, bearer_timer_cb, 0);<BR> bearer_mode = mode;<BR> bearer_cb = cb;<BR> return MS_SOC_WAIT;<BR> }<BR> return MS_SOC_OK;<BR>}</DIV>
<DIV>int ms_bearer_close()<BR>{<BR> if (bearer_status)<BR> {<BR> ms_quick_timer(2000, 1, bearer_timer_cb, 0);<BR> return MS_SOC_WAIT;<BR> }<BR> return MS_SOC_OK;<BR>}</DIV>
<DIV>void * _vm_soc_session_malloc()<BR>{<BR> int i;<BR> soc_session_t* session = NULL;<BR> for (i = 0; i < MS_SOC_MAX_NUM; i++) <BR> {<BR> if (!sessions.used) {<BR> session = sessions + i;<BR> session->handle = i;<BR> break;<BR> }<BR> } <BR> return session;<BR>}<BR>void _ms_soc_session_free(int handle)<BR>{<BR> if (handle >= 0 && handle <= MS_SOC_MAX_NUM)<BR> {<BR> sessions.tcp_state = TCP_WAIT_CLOSE;<BR> sessions.used = FALSE;<BR> sessions.soc_cb = NULL;<BR> }<BR>}<BR>void * _ms_soc_session_get(int handle)<BR>{<BR> return sessions+handle;<BR>}<BR>int ms_soc_create(int type, void * cb)<BR>{<BR> soc_session_t* session;</DIV>
<DIV> session = _vm_soc_session_malloc();<BR> if (session)<BR> {<BR> unsigned long ul = 1;<BR> unsigned long p = 0;<BR> session->tcp_state = TCP_CONNECTING;<BR> session->used = TRUE;<BR> session->soc_cb = cb;</DIV>
<DIV> if ((session->socket = socket(PF_INET, type+1, 0)) == INVALID_SOCKET)<BR> {<BR> _ms_soc_session_free(session->handle);<BR> return MS_SOC_ERROR;<BR> }</DIV>
<DIV> if(ioctlsocket(session->socket, FIONBIO, (unsigned long*)&ul) == SOCKET_ERROR)<BR> {<BR> _ms_soc_session_free(session->handle);<BR> return MS_SOC_ERROR;<BR> }</DIV>
<DIV> if (ioctlsocket(session->socket, FIONREAD, &p) != 0)<BR> {<BR> _ms_soc_session_free(session->handle);<BR> return MS_SOC_ERROR;<BR> }</DIV>
<DIV> return session->handle;<BR> }<BR> return MS_SOC_USEOUT;<BR>}</DIV>
<DIV>//////////////////////////////////////////////////////<BR>int ms_soc_create_udp(int type, void * cb)</DIV>
<DIV>{<BR> soc_session_t* session;<BR> <BR> session = _vm_soc_session_malloc();<BR> if (session)<BR> {<BR> unsigned long ul = 1;<BR> unsigned long p = 0;<BR> session->udp_state = UDP_CONNECTING;<BR> session->used = TRUE;<BR> session->soc_cb = cb;<BR> <BR> if ((session->socket = socket(PF_INET, type, 0)) == INVALID_SOCKET)<BR> {<BR> _ms_soc_session_free(session->handle);<BR> return MS_SOC_ERROR;<BR> }<BR> <BR> if(ioctlsocket(session->socket, FIONBIO, (unsigned long*)&ul) == SOCKET_ERROR)//控制套接口的模式<BR> {<BR> _ms_soc_session_free(session->handle);<BR> return MS_SOC_ERROR;<BR> }<BR> <BR> if (ioctlsocket(session->socket, FIONREAD, &p) != 0)<BR> {<BR> _ms_soc_session_free(session->handle);<BR> return MS_SOC_ERROR;<BR> }<BR> <BR> return session->handle;<BR> }<BR> return MS_SOC_USEOUT;<BR>}</DIV>
<DIV>int ms_soc_close(int s)<BR>{<BR> int handle = s;<BR> if ((handle >= 0) && (handle < MS_SOC_MAX_NUM)) <BR> {<BR> if (sessions.handle == handle) <BR> {<BR> closesocket(sessions.socket);<BR> _ms_soc_session_free(handle);</DIV>
<DIV> return MS_SOC_OK;<BR> }<BR> } </DIV>
<DIV> return MS_SOC_INVALID;<BR>}</DIV>
<DIV>int ms_soc_bind(int s, ms_sockaddr * addr)<BR>{<BR> int handle,err;<BR>// int len;<BR> soc_session_t* session;<BR> struct sockaddr_in udp_bind;//标准的套接字结构体sockaddr_in<BR> ms_sockaddr *addr_udp=NULL;<BR> addr_udp=addr;<BR> handle=s;<BR> session = _ms_soc_session_get(s);//return sessions+handle;返回的应该是socket的值<BR> if (session)<BR> {<BR> udp_bind.sin_family = AF_INET;<BR> udp_bind.sin_port = htons((unsigned short)addr->port);<BR> udp_bind.sin_addr.s_addr = *(long*)addr->addr;<BR> <BR> }</DIV>
<DIV> if ((handle >= 0) && (handle < MS_SOC_MAX_NUM)) <BR> {<BR> if (sessions.handle == handle) <BR> {<BR> err=bind(s,(struct sockaddr *)&addr,sizeof(addr));<BR> if(err==SOCKET_ERROR)<BR> return MS_SOC_ERROR;<BR> else <BR> return MS_SOC_OK;<BR> }<BR> } <BR> <BR> return 0;<BR>}</DIV>
<DIV><BR>int ms_soc_connect(int s, const ms_sockaddr * addr)<BR>{<BR> int idx = -1;<BR> soc_session_t* session;<BR> struct sockaddr_in remote;<BR> unsigned long p = 0;</DIV>
<DIV> int TimeOut = 5000;<BR> unsigned long ul = 1;<BR> struct timeval timeout;<BR> fd_set r;<BR> int ret;<BR> <BR> session = _ms_soc_session_get(s);<BR> if (session)<BR> {<BR> remote.sin_family = AF_INET;<BR> remote.sin_port = htons((unsigned short)addr->port);<BR> remote.sin_addr.s_addr = *(long*)addr->addr;</DIV>
<DIV> if (connect(session->socket, (struct sockaddr*)&remote, sizeof(remote)) == SOCKET_ERROR)<BR> {<BR> if (WSAGetLastError() == WSAEWOULDBLOCK)<BR> {<BR> int error_code, err_len=sizeof(error_code);<BR> FD_ZERO(&r);<BR> FD_SET(session->socket, &r);<BR> timeout.tv_sec = 10; //Connection timeout<BR> timeout.tv_usec = 0;<BR> ret = select(session->socket+1, 0, &r, 0, &timeout);</DIV>
<DIV> if ( ret <= 0 )<BR> {<BR> ret = closesocket(session->socket);<BR> _ms_soc_session_free(s);<BR> return MS_SOC_ERROR;<BR> }</DIV>
<DIV> if (FD_ISSET(session->socket, &r))<BR> {<BR> getsockopt(session->socket, SOL_SOCKET, SO_ERROR, (char *)&error_code, &err_len);<BR> if (error_code != 0)<BR> {<BR> ret = closesocket(session->socket);<BR> _ms_soc_session_free(s);<BR> return MS_SOC_ERROR;<BR> }<BR> }<BR> else<BR> {<BR> ret = closesocket(session->socket);<BR> _ms_soc_session_free(s);<BR> return MS_SOC_ERROR;<BR> }<BR> }<BR> else<BR> {<BR> _ms_soc_session_free(idx);<BR> return MS_SOC_ERROR;<BR> }<BR> return MS_SOC_WAIT;<BR> }<BR> <BR> if(ioctlsocket(session->socket, FIONBIO, (unsigned long*)&p) == SOCKET_ERROR)<BR> {<BR> closesocket(session->socket);<BR> return MS_SOC_ERROR;<BR> }<BR> }<BR> return MS_SOC_INVALID;<BR>}</DIV>
<DIV>int ms_soc_recvfrom(int s,void *buf,int len,ms_sockaddr *addr)<BR>{<BR> int handle = s;<BR> int nread;<BR> int serverlen;<BR> //int v;<BR>// fd_set fdwrs_udp;<BR> struct timeval timeout = {0, 0};<BR> soc_session_t* session;<BR> <BR> struct sockaddr_in remote_udp;//标准的套接字结构体sockaddr_in<BR> ms_sockaddr *addr_udp=NULL;<BR> addr_udp=addr;//接收下看看<BR> serverlen=sizeof(remote_udp);<BR> //sessions.write_pipe =CAN_WRITE;<BR> session = _ms_soc_session_get(s);//return sessions+handle;返回的应该是socket的值<BR> if (session)<BR> {<BR> //把自己定义的放到标准的里边<BR> remote_udp.sin_family = AF_INET;<BR> remote_udp.sin_port = htons((unsigned short)addr->port);<BR> remote_udp.sin_addr.s_addr = *(long*)addr->addr;//是否正确???<BR> //sockSend.sin_addr.S_un.S_addr=inet_addr("211.143.108.24");//服务器地址??传递是否正确<BR> }<BR> <BR> handle=s;//接收句柄<BR> /*<BR> if ((handle >= 0) && (handle < MS_SOC_MAX_NUM) && <BR> sessions.used && (sessions.handle == handle))<BR> {<BR> if (sessions.udp_state == UDP_WAIT_CLOSE)<BR> return -1;<BR> */<BR> nread = recvfrom(sessions.socket, (char*)buf, len, 0,(struct sockaddr*)&remote_udp,&serverlen);<BR>/*<BR> if (sessions.read_pipe == CAN_READ <BR> && sessions.udp_state == UDP_CONNECTED)<BR> {<BR> <BR> int v;<BR> fd_set fdwrs;<BR> struct timeval timeout = {0, 0};<BR> <BR> FD_ZERO(&fdwrs);<BR> FD_SET(sessions.socket, &fdwrs);<BR> <BR> if ((v = select(1, &fdwrs, NULL, NULL, &timeout)) == SOCKET_ERROR) <BR> {<BR> return MS_SOC_ERROR;<BR> }<BR> if (v > 0 && FD_ISSET(sessions.socket, &fdwrs)) <BR> {<BR> nread = recvfrom(sessions.socket, (char*)buf, len, 0,(struct sockaddr*)addr,(int *)sizeof(ms_sockaddr));<BR> }<BR> else<BR> {<BR> return MS_SOC_WAIT;<BR> } <BR> </DIV>
<DIV> <BR> * nread == 0 表示TCP链路已经被对等层关闭。<BR> * SOCKET_ERROR 并且调用WSAGetLastError()返回WSAEWOULDBLOCK写通道当前被阻塞,其他为失败。<BR> * nread > 0表示已经写入了一定的字节数。<BR> <BR> if (nread == 0) <BR> {<BR> //收到Server的FIN包,可以选择主动断开连接或继续发送数据;<BR> //ms_soc_close(s);<BR> //nread = -1;<BR> } <BR> else if (nread == SOCKET_ERROR) <BR> {<BR> switch(WSAGetLastError())<BR> {<BR> case WSAEWOULDBLOCK:<BR> sessions.read_pipe = BLOCK_READ;<BR> nread = MS_SOC_WAIT;<BR> break;<BR> default:<BR> nread = -1;<BR> break;<BR> }<BR> }<BR> <BR> return nread;<BR> }<BR> else<BR> return MS_SOC_WAIT;<BR> } <BR> else<BR> return MS_SOC_INVALID;<BR> */<BR> return nread;<BR>}</DIV>
<DIV><BR>int ms_soc_recv(int s, void * buf, int len)<BR>{<BR> int handle = s;<BR> int nread;<BR> <BR> if ((handle >= 0) && (handle < MS_SOC_MAX_NUM) && <BR> sessions.used && (sessions.handle == handle)) <BR> {<BR> if (sessions.tcp_state == TCP_WAIT_CLOSE)<BR> return -1;<BR> <BR> if (sessions.read_pipe == CAN_READ <BR> && sessions.tcp_state == TCP_CONNECTED)<BR> {<BR> /***************************************/<BR> int v;<BR> fd_set fdwrs;<BR> struct timeval timeout = {0, 0};<BR> <BR> FD_ZERO(&fdwrs);<BR> FD_SET(sessions.socket, &fdwrs);<BR> <BR> if ((v = select(1, &fdwrs, NULL, NULL, &timeout)) == SOCKET_ERROR) <BR> {<BR> return MS_SOC_ERROR;<BR> }<BR> if (v > 0 && FD_ISSET(sessions.socket, &fdwrs)) <BR> {<BR> nread = recv(sessions.socket, (char*)buf, len, 0);<BR> }<BR> else<BR> {<BR> return MS_SOC_WAIT;<BR> } <BR> /***************************************/</DIV>
<DIV> /*<BR> * nread == 0 表示TCP链路已经被对等层关闭。<BR> * SOCKET_ERROR 并且调用WSAGetLastError()返回WSAEWOULDBLOCK写通道当前被阻塞,其他为失败。<BR> * nread > 0表示已经写入了一定的字节数。<BR> */<BR> if (nread == 0) <BR> {<BR> //收到Server的FIN包,可以选择主动断开连接或继续发送数据;<BR> //ms_soc_close(s);<BR> //nread = -1;<BR> } <BR> else if (nread == SOCKET_ERROR) <BR> {<BR> switch(WSAGetLastError())<BR> {<BR> case WSAEWOULDBLOCK:<BR> sessions.read_pipe = BLOCK_READ;<BR> nread = MS_SOC_WAIT;<BR> break;<BR> default:<BR> nread = -1;<BR> break;<BR> }<BR> }<BR> <BR> return nread;<BR> }<BR> else<BR> return MS_SOC_WAIT;<BR> }<BR> else<BR> return MS_SOC_INVALID;</DIV>
<DIV>}<BR>/***************************************************************************************************************************************************************************<BR>*具体解释 select 的参数:</DIV>
<DIV> int maxfdp 是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错!在 Windows 中这个参数值无所谓,可以设置不正确。</DIV>
<DIV> fd_set* readfds 是指向 fd_set 结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的读变化的,即我们关心是否可以从这些文件中读取数据了,如果这个集合中有一个文件可读,select 就会返回一个大于 0 的值,表示可读取的文件数量,如果没有可读的文件,则根据 timeout 参数再判断是否超时,若超出 timeout 的时间,select 返回 0,若发生错误返回负值。这个参数也可以传入 NULL 值,表示不关心任何文件的读变化。</DIV>
<DIV> fd_set* writefds 是指向 fd_set 结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的写变化的,即我们关心是否可以向这些文件中写入数据了,如果这个集合中有一个文件可写,select 就会返回一个大于 0 的值,表示可写入的文件数量,如果没有可写的文件,则根据 timeout 参数再判断是否超时,若超出 timeout 的时间,select 返回 0,若发生错误返回负值。这个参数也可以传入 NULL值,表示不关心任何文件的写变化。</DIV>
<DIV> fe_set* errorfds 同上面两个参数的一样,用来监视文件错误异常。</DIV>
<DIV> struct timeval* timeout 是 select 的超时时间,这个参数至关重要,它可以使 select 处于三种状态。</DIV>
<DIV> 第一:若将 NULL 以形参传入,即不传入时间结构,就是将 select 置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;</DIV>
<DIV> 第二:若将时间值设为 0 秒 0 微妙,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回 0,有变化返回一个正值;</DIV>
<DIV> 第三:timeout 的值大于 0,这就是等待的超时时间,即 select 在 timeout 时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。 <BR>**************************************************************************************************************************************************************************/</DIV>
<DIV>int ms_soc_sendto(int s,const void *buf,int len,ms_sockaddr *addr)<BR>{<BR> int handle;<BR> int nwrite;<BR>// int v;<BR>// fd_set fdwrs_udp;<BR> struct timeval timeout = {0, 0};<BR> soc_session_t* session;<BR> <BR> struct sockaddr_in remote_udp;//标准的套接字结构体sockaddr_in<BR> ms_sockaddr *addr_udp=NULL;<BR> addr_udp=addr;//接收下看看<BR> //sessions.write_pipe =CAN_WRITE;<BR> session = _ms_soc_session_get(s);//return sessions+handle;返回的应该是socket的值<BR> if (session)<BR> {<BR> //把自己定义的放到标准的里边<BR> remote_udp.sin_family = AF_INET;<BR> remote_udp.sin_port = htons((unsigned short)addr->port);<BR> remote_udp.sin_addr.s_addr = *(long*)addr->addr;//是否正确???<BR> //sockSend.sin_addr.S_un.S_addr=inet_addr("211.143.108.24");//服务器地址??传递是否正确<BR> }</DIV>
<DIV> handle=s;//接收句柄<BR> <BR> /*<BR> <BR> FD_ZERO(&fdwrs_udp);<BR> FD_SET(sessions.socket, &fdwrs_udp);<BR> <BR> if ((v = select(1, NULL, &fdwrs_udp, NULL, &timeout)) == SOCKET_ERROR) <BR> {<BR> return MS_SOC_ERROR;<BR> }<BR> */<BR> nwrite = sendto(sessions.socket, (char*)buf, len, 0,(struct sockaddr*)&remote_udp,sizeof(remote_udp));<BR> /*<BR> if (v > 0 && FD_ISSET(sessions.socket, &fdwrs_udp)) <BR> {<BR> nwrite = sendto(sessions.socket, (char*)buf, len, 0,(struct sockaddr*)&remote_udp,sizeof(remote_udp));<BR> //标准sendto改变<BR> }<BR> else<BR> {<BR> return MS_SOC_WAIT;<BR> } <BR> <BR> */<BR> /*<BR> if ((handle >= 0) && (handle < MS_SOC_MAX_NUM) && <BR> sessions.used && (sessions.handle == handle))//用于并发事件判断 <BR> {</DIV>
<DIV> if (sessions.udp_state == UDP_WAIT_CLOSE)//状态判断<BR> return -1;</DIV>
<DIV> // if (sessions.write_pipe == CAN_WRITE<BR> // && sessions.udp_state == UDP_CONNECTED)//写入状态判断<BR> // {</DIV>
<DIV> int v;<BR> fd_set fdwrs_udp;<BR> struct timeval timeout = {0, 0};<BR> <BR> FD_ZERO(&fdwrs_udp);<BR> FD_SET(sessions.socket, &fdwrs_udp);<BR> <BR> if ((v = select(1, NULL, &fdwrs_udp, NULL, &timeout)) == SOCKET_ERROR) <BR> {<BR> return MS_SOC_ERROR;<BR> }</DIV>
<DIV><BR> if (v > 0 && FD_ISSET(sessions.socket, &fdwrs_udp)) <BR> {<BR> nwrite = sendto(sessions.socket, (char*)buf, len, 0,(struct sockaddr*)&remote_udp,sizeof(remote_udp));<BR> //标准sendto改变<BR> }<BR> else<BR> {<BR> return MS_SOC_WAIT;<BR> } <BR> <BR> /* 单独错误处理<BR> if (nwrite == SOCKET_ERROR)<BR> {<BR> switch(WSAGetLastError())<BR> {<BR> case WSAEWOULDBLOCK:<BR> sessions.write_pipe = BLOCK_WRITE;<BR> nwrite = MS_SOC_WAIT;<BR> break;<BR> default:<BR> nwrite = -1;<BR> break;<BR> } <BR> }</DIV>
<DIV> <BR> }<BR> else<BR> return nwrite;<BR> }<BR> else<BR> return MS_SOC_WAIT;<BR> }<BR> <BR> */<BR> return MS_SOC_INVALID;//最外边返回值<BR>}</DIV>
<DIV>int ms_soc_send(int s, const void * buf, int len)<BR>{<BR> int handle = s;<BR> int nwrite;</DIV>
<DIV> if ((handle >= 0) && (handle < MS_SOC_MAX_NUM) && <BR> sessions.used && (sessions.handle == handle)) <BR> {<BR> if (sessions.tcp_state == TCP_WAIT_CLOSE)<BR> return -1;</DIV>
<DIV> if (sessions.write_pipe == CAN_WRITE<BR> && sessions.tcp_state == TCP_CONNECTED)<BR> {</DIV>
<DIV> int v;<BR> fd_set fdwrs;<BR> struct timeval timeout = {0, 0};<BR> <BR> FD_ZERO(&fdwrs);<BR> FD_SET(sessions.socket, &fdwrs);<BR> <BR> if ((v = select(1, NULL, &fdwrs, NULL, &timeout)) == SOCKET_ERROR) <BR> {<BR> return MS_SOC_ERROR;<BR> }<BR> if (v > 0 && FD_ISSET(sessions.socket, &fdwrs)) <BR> {<BR> nwrite = send(sessions.socket, (char*)buf, len, 0);<BR> }<BR> else<BR> {<BR> return MS_SOC_WAIT;<BR> } </DIV>
<DIV> if (nwrite == SOCKET_ERROR)<BR> {<BR> switch(WSAGetLastError())<BR> {<BR> case WSAEWOULDBLOCK:<BR> sessions.write_pipe = BLOCK_WRITE;<BR> nwrite = MS_SOC_WAIT;<BR> break;<BR> default:<BR> nwrite = -1;<BR> break;<BR> } <BR> } <BR> return nwrite;<BR> }<BR> else <BR> return MS_SOC_WAIT; <BR> }<BR> else<BR> return MS_SOC_INVALID;<BR>}</DIV>
<DIV>int ms_inet_addr(char * ipchar, uint8 * ip)<BR>{<BR> uint32 ipp = inet_addr(ipchar);<BR> if (ip)<BR> memcpy(ip, &ipp, 4);<BR> return ipp;<BR>}</DIV>
<DIV>void get_host_timer_cb(int tid, int p) <BR>{<BR> soc_session_t* session = NULL;<BR> session = (soc_session_t*)_ms_soc_session_get(p);<BR> if (session)<BR> {<BR> if (session->get_host_cb)<BR> session->get_host_cb(p, *(long*)session->addr.addr);<BR> }<BR>}</DIV>
<DIV>int ms_soc_gethostbyname(int s, const char * host, void * cb)<BR>{<BR> int ip;<BR> HOSTENT* hent;<BR> static char g_host;<BR> soc_session_t* session = NULL;</DIV>
<DIV> session = (soc_session_t*)_ms_soc_session_get(s);<BR> if (session)<BR> {<BR> if ((hent = gethostbyname(host)) != 0)<BR> {<BR> ip = *(long*)hent->h_addr;<BR> if (strcmp(g_host, host) == 0)<BR> {<BR> return ip;<BR> }<BR> else<BR> {<BR> memcpy(session->addr.addr, &ip, sizeof(long));<BR> session->get_host_cb = cb;<BR> ms_quick_timer(200, s, get_host_timer_cb, 0);<BR> strcpy(g_host, host);<BR> return MS_SOC_WAIT;<BR> }<BR> }<BR> return MS_SOC_ERROR;<BR> }<BR> return MS_SOC_INVALID;<BR>}<BR></DIV>
页:
[1]