一、说明
使用UDP时,直接使用API代替控件。
第一个程序(ReadBufferUdp)使用来接收到缓存中。
“Destino”变量非常重要,如果你从其他地方接收数据到Buffer,你必须设置Destino = 0 并且在以后执行的时候赋值你将要发送的包的地址给它(after the execution it will have the address which send you the packet.)。
如果你只想从一个指定的地址接收数据,你必须设置变量Destino = <address>.
“gvEncerrar” 用来中止处理过程。(gvEncerrar被设置为全局变量。)
超时时间设置。”Inicio + 12″ = 12 sec of timeout.
第三个程序是用来准备WinSock程序。
二、代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
int ReadBufferUdp(unsigned long *Destino,void *T,int Size) { char Buffer[128]; SOCKADDR_IN SockAddr; int LenSockAddr=sizeof(SOCKADDR_IN); fd_set FdRead; struct timeval t_val; int Ret; time_t Inicio = time(NULL); Application->ProcessMessages(); if(gvEncerrar) return false; FD_ZERO(&FdRead); FD_SET(gvSocket,&FdRead); t_val.tv_sec=0; t_val.tv_usec=0; while((Ret=select(0,&FdRead,NULL,NULL,&t_val))!=1 && (Inicio + 12) > time(NULL) && !gvEncerrar) { FD_ZERO(&FdRead); FD_SET(gvSocket,&FdRead); t_val.tv_sec=0; t_val.tv_usec=0; Application->ProcessMessages(); } if(Ret != 1) return false; if(recvfrom(gvSocket,Buffer,Size,0,(LPSOCKADDR)&SockAddr,&LenSockAddr)!=Size) return false; if(*Destino == 0) { *Destino = SockAddr.sin_addr.s_addr; } else if(*Destino != SockAddr.sin_addr.s_addr) return false; memcpy(T,Buffer,Size); return true; } int WriteBufferUdp(unsigned long Destino,void *T,int Size) { SOCKADDR_IN SockAddr; int Sent; Application->ProcessMessages(); SockAddr.sin_family = AF_INET; SockAddr.sin_port = gvPortUdp; SockAddr.sin_addr.s_addr = Destino; Sent = sendto(gvSocket,(char*)T,Size,0,(LPSOCKADDR)&SockAddr,sizeof(SockAddr)); if(Sent != Size) return false; else return true; } void InicializaTCPIP() { WORD wVersionRequested; WSADATA wsaData; IN_ADDR In; PSERVENT PServent; SOCKADDR_IN SockAddrIn; wVersionRequested = MAKEWORD( 1, 1 ); if(WSAStartup( wVersionRequested, &wsaData )) { ShowMessage("Erro na inicializao do TCP/IP"); Application->Terminate(); return; } // Get the port on service file if((PServent=getservbyname("your_service_name","udp"))==NULL) { ShowMessage("Erro obtendo port do servi transurb/udp"); Application->Terminate(); return; } gvPortUdp = PServent->s_port; sprintf(StrAux,"Servi transurb/udp port:%d",ntohs(gvPortUdp)); Log(StrAux); // Open de Socket if((gvSocket = socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET) { ShowMessage("Erro na criao do socket"); Application->Terminate(); return; } Log("Socket criado com sucesso"); // Do the bind SockAddrIn.sin_family = AF_INET; SockAddrIn.sin_port = gvPortUdp; SockAddrIn.sin_addr.s_addr = NULL; if(bind(gvSocket,(LPSOCKADDR)&SockAddrIn,sizeof(SockAddrIn))==SOCKET_ERROR) { ShowMessage("Erro no bind do socket"); Application->Terminate(); return; } Log("Bind do socket com sucesso"); } |