/* Demo program for UDP server & client 可以下命令切換連線 IP/port。 可以下命令切換 server listen 的 port. 輸入的一般訊息就直接送往遠端的 server。(有連線成功的話) (但如果對方不存在的話 -->???) [2009/03/25] 加上tcp echo server 測試 */ #include #include #include #include "..\lib\8000A.h" #include "..\lib\tcpip32.h" #define BUFSIZE 1024 /* read/write buffer size */ #define SOCKETS NCONNS /* define the maximum number of sockets */ #define QLEN (SOCKETS-1) /* maximum connection queue length */ #define UDP_BUFFER_SIZE 1472 #define INADDR_BROADCAST 0xffffffffUL //255.255.255.255 #define INADDR_ANY 0x00000000UL extern int errno; //------------------------------------------------------------------------------ // tcp echo server //------------------------------------------------------------------------------ char Message1[]="connected successful.\r\n"; char Message2[]="Server is busy...\r\n"; char buf[BUFSIZE+1],SendBack[BUFSIZE+1]; int do_echo( int skt ) { int i, cc, err=0; //err = cc = readsocket( skt, buf, sizeof(buf) ); err = cc = recv( skt, buf, BUFSIZE,0 ); if (err == 0) { /* disconnected */ shutdown( skt, 0 ); closesocket( skt ); Print("[Socket %d is disconnected from the client side.]",skt); return err; } if (err < 0) { /* read error */ Print("[Socket %d :read error.errno=%d]",skt,errno); shutdown( skt, 0 ); closesocket( skt ); return err; } buf[cc] = '\0'; err= send(skt,buf,cc,0); if (err < 0) { /* write error */ Print( "echo write error= %d\r\n", errno ); shutdown( skt, 0 ); closesocket( skt ); return err; } // if (!strncmp("down", buf,4)) { /* shutdown echo server */ // es = 0; // } return err; } //------------------------------------------------------------------------------ int DoEchoServer(int skt, int *cli_Skt) { struct sockaddr_in ssin; int sin_len; int tmpSkt,err; unsigned char *ip; Print("new client connect in\r\n"); memset( &ssin, 0, sizeof(ssin) ); tmpSkt = accept( skt, (struct sockaddr *)&ssin, &sin_len ); if (tmpSkt < 0){ Print( "accept error =%d\r\n", errno ); } else if(*cli_Skt>=0){ err=send( tmpSkt, Message2, strlen(Message2), 0 ); closesocket( tmpSkt ); } else { *cli_Skt=tmpSkt; //Print("new connected socket=%d\r\n",ss); ip=(unsigned char *)&ssin.sin_addr.s_addr; Print("new connected socket=%d:\r\nIP=%d.%d.%d.%d:%u,NET=%d\r\n",*cli_Skt, ip[0],ip[1],ip[2],ip[3],SwapShort(ssin.sin_port),connblo[*cli_Skt].netno ); err=send( *cli_Skt, Message1, strlen(Message1), 0 ); connblo[*cli_Skt].txstat |= S_KEEPA; } } //------------------------------------------------------------------------------ int TcpListen(unsigned port) { int skt,err; struct sockaddr_in ssin; /* client Internet endpoing address */ int sin_len; /* length of sockaddr_in */ skt = socket( PF_INET, SOCK_STREAM, 0 ); if (skt < 0) { Print( "can't create socket! errno=%d\r\n", errno ); return -1; } else Print("Server socket is %d\r\n",skt); Print("(1)socket()-->netno=%d\r\n",connblo[skt].netno); /******************************** * addressing for master socket * ********************************/ memset( &ssin, 0, sizeof(ssin) ); /* bzero is a unix system call */ ssin.sin_family = AF_INET; // ssin.sin_addr.s_addr = 0; /* for listen on both netno=0 & 1 */ ssin.sin_addr.s_addr = netconf[1].Iaddr.l; // netconf[1] for netno=0, netconf[3] for netno=1. ssin.sin_port = htons( port ); /******************* * bind the socket * *******************/ err = bind( skt, (struct sockaddr *)&ssin, sizeof(ssin) ); if (err < 0) { Print( "can't bind to TCP port %u, errno=%d\r\n", port, errno ); closesocket( skt ); return -1; } Print("(2)bind()-->netno=%d\r\n",connblo[skt].netno); /****************** * make listening * ******************/ err = listen( skt, 3 ); if (err < 0) { Print( "can't Listen TCP port %u, errno=%d\r\n", port, errno ); closesocket( skt ); return -1; } Print("(3)listen()-->netno=%d\r\n",connblo[skt].netno); return skt; } //------------------------------------------------------------------------------ //unsigned UdpListenPort=54321; unsigned UdpListenPort=57188; //------------------------------------------------------------------------------ int bAutoTest=0; unsigned TestData=0xFFFF; //------------------------------------------------------------------------------ extern long ET_TOUT; extern int errno; int UcSkt=-1; // UDP client socket int UsSkt=-1; // UDP server socket char RemoteUdpIp[30]="10.0.9.239"; //unsigned RemoteUdpPort=57188; unsigned RemoteUdpPort=54321; //unsigned RemoteUdpPort=23; char TestUdpClientMsg[]="ICPDAS7188E,00\r"; char TestUdpServerMsg[]= /* test message */ "ICPDAS7188E,80,NAME=7188EA,ALIAS=test1,LOCK=0,DHCP=0,IP=10.0.8.235," "MASK=255.255.255.0,GATEWAY=10.0.9.254,MAC=00:0d:e0:d9:16:24\r\n"; //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ int EnableUdpBroadcast(int skt) { int i,len; if(!getsockopt(skt, SOL_SOCKET, SO_BROADCAST, (char *)&i, &len)){ if(!i){ i=1; if (setsockopt(skt, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0) { /* if this fails, close previously opened ethernet socket and return */ Print("\r\nCan not enable broadcast for the UDP socket!!!\r\n"); return -1; } else { Print("\r\nEnable broadcast for the UDP socket OK!!!\r\n"); } } else { Print("\r\nSkt %d is already enable broadcast for the UDP socket!!!\r\n",UsSkt); } } else { Print("\r\nCan not read the broadcast flag for the UDP socket!!!\r\n"); return -2; } return 0; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void SendUdpBroadcastMsg(void) { struct sockaddr_in sockAddr; int i; int netno; long broadcastIp; unsigned char *ip; if(UcSkt < 0) return; // if(RemoteUdpPort == 57188){ netno=connblo[UcSkt].netno; broadcastIp=(~netconf[1+netno*2].Imask.l) | netconf[1+netno*2].Iaddr.l; ip=(unsigned char *)&broadcastIp; Print("[Broadcast UDP Search Cmd to %d.%d.%d.%d:57188]",ip[0],ip[1],ip[2],ip[3]); memset( &sockAddr, 0, sizeof(sockAddr) ); sockAddr.sin_port = htons(57188); /* set IP address to broadcast to all nodes on net */ // sockAddr.sin_addr.s_addr = INADDR_BROADCAST; //htonl(INADDR_BROADCAST); sockAddr.sin_addr.s_addr =broadcastIp; //inet_addr("10.0.9.255"); /* set protocol family in case it hasn't been done already */ sockAddr.sin_family = AF_INET; // EnableUdpBroadcast(UcSkt); i = sendto(UcSkt, TestUdpClientMsg, sizeof(TestUdpClientMsg)-1, 0, (struct sockaddr *) &sockAddr, sizeof(sockAddr)); if (i < 0) { //do nothing - no retry mechanism Print("sendto failed A: return = %d,errno=%d (Broadcast)\r\n",i,errno); } else { Print("send broadcast message OK\r\n"); } // } // else { // Print("Do nothing\r\n"); // } } int Quit=0; char InDataBuf[UDP_BUFFER_SIZE+1]; int length; int bInCmdMode=0; #define MAX_CMD_LEN 256 int CmdIdx=0; char CmfBuf[MAX_CMD_LEN+1]; int netno=255; void ShowPrompt(void); static struct sockaddr_in sin,UcSin; //------------------------------------------------------------------------------ int UdpConnect(int netno,char *RemoteIp,unsigned UdpPort) { connblo[UcSkt].netno=netno; // 指定使用的 netno, 255 表是不指定。 memset( &UcSin, 0, sizeof(UcSin) ); UcSin.sin_family = AF_INET; UcSin.sin_addr.s_addr = inet_addr(RemoteIp); UcSin.sin_port = htons( UdpPort ); if (connect(UcSkt, (struct sockaddr *)&UcSin, sizeof(UcSin))) { // on success return 0 Print("connect() failed: %d\r\n", errno); return -1; } return 0; // success } //------------------------------------------------------------------------------ int UdpListen(int netno,unsigned UdpPort) { int skt; skt = socket( PF_INET, SOCK_DGRAM, 0 ); /* UDP/IP */ if (skt < 0) { Print( "can't create socket! error %d,errno=%d\r\n", UsSkt,errno ); return skt; } connblo[skt].netno=netno; memset( &sin, 0, sizeof(sin) ); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; // htonl(INADDR_ANY); sin.sin_port = htons( UdpPort ); /* bind socket */ if (bind(skt, (struct sockaddr *) &sin, sizeof(sin)) < 0) { /* if this fails, close previously opened ethernet socket and return */ Print("\r\nCan not bind the UDP socket\r\n"); closesocket(skt); return -1; } return skt; // success } //------------------------------------------------------------------------------ void DoUdpClientSocket(void) { int i; int len; struct sockaddr_in sain; void SendTestPattern(void); len = recvfrom(UcSkt, InDataBuf, UDP_BUFFER_SIZE, 0, (struct sockaddr *) &sain, &i); if(len>0){ if(bAutoTest){ if(len==2){ if(TestData==*(unsigned *)InDataBuf){ SendTestPattern(); } else { Print("--> data error(%04X)\r\n",*(unsigned *)InDataBuf); } } else { Print("--> length error(%d)",len); } } else { InDataBuf[len]=0; //Print("Client Skt receive:"); Puts(InDataBuf); } } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void DoUdpServerSocket(void) { int i; int len; unsigned char *ip; struct sockaddr_in sain; len = recvfrom(UsSkt, InDataBuf, UDP_BUFFER_SIZE, 0, (struct sockaddr *) &sain, &i); if(len>0){ InDataBuf[len]=0; ip=(unsigned char *)&sain.sin_addr.s_addr; Print("Server Skt receive from IP=%d.%d.%d.%d Port=%u,netno=%d:\r\n", ip[0],ip[1],ip[2],ip[3], SwapShort(sain.sin_port),connblo[UsSkt].netno); Puts(InDataBuf); Puts("\r\n"); if(UdpListenPort == 57188){ //if(connblo[UsSkt].netno==1){ //來自netno=1 的才回應 sain.sin_port = htons(RemoteUdpPort); /* set IP address to broadcast to all nodes on net */ sain.sin_addr.s_addr = INADDR_BROADCAST; //htonl(INADDR_BROADCAST); /* set protocol family in case it hasn't been done already */ sain.sin_family = AF_INET; EnableUdpBroadcast(UsSkt); TestUdpServerMsg[25]='0'+connblo[UsSkt].netno; i = sendto(UsSkt, TestUdpServerMsg, sizeof(TestUdpServerMsg)-1, 0, (struct sockaddr *) &sain, sizeof(sain)); if (i < 0) { //do nothing - no retry mechanism Print("sendto failed A: return = %d,errno=%d (Broadcast)\r\n",i,errno); } else { Print("send broadcast message OK\r\n"); } //} } else { i = sendto(UsSkt, InDataBuf, len, 0, (struct sockaddr *) &sain, sizeof(sain)); } if(bInCmdMode){ ShowPrompt(); } } } //------------------------------------------------------------------------------ long ttTest; void SendTestPattern(void) { int i; TestData++; i = sendto(UcSkt, &TestData, 2, 0, (struct sockaddr *) &UcSin, sizeof(UcSin)); ttTest=GetTimeTicks(); Print("\r[%04X]",TestData); if(!TestData) Print("<%lu>\r\n",GetTimeTicks()); } //------------------------------------------------------------------------------ void SendTestPatternAgain(void) { Print("<%lu:%04X>\r\n",GetTimeTicks(),TestData); TestData--; SendTestPattern(); } //------------------------------------------------------------------------------ void ShowPrompt(void) { Puts("\r\nCmd>"); } //------------------------------------------------------------------------------ void DoCmd(void) { int i; char *ptr; int assign; if(!CmdIdx) return; CmdToArg(CmfBuf); ptr=strchr(Argv[0],'='); if(ptr){ *ptr++=0; assign=1; } else { assign=0; } if(!stricmp(Argv[0],"connect")){ if(Argc>=2){ strcpy(RemoteUdpIp,Argv[1]); if(Argc>=3){ RemoteUdpPort=atoi(Argv[2]); } } if(UdpConnect(netno,RemoteUdpIp,RemoteUdpPort)){ Print("connect() failed: %d\r\n", errno); } else { Print("Connect to %s:%u",RemoteUdpIp,RemoteUdpPort); } } else if(!stricmp(Argv[0],"listen")){ if(Argc>=2){ UdpListenPort=atoi(Argv[1]); } if(UsSkt >= 0) closesocket(UsSkt); UsSkt=UdpListen(255,UdpListenPort); if (UsSkt < 0) { Print("UDP Listen Error,errno=%d\r\n",errno); } else { Print("Listen UDP port %u Success,socket=%d\r\n",UdpListenPort,UsSkt); } } else if(!stricmp(Argv[0],"net")){ netno=atoi(ptr); Print("Set netno to %d",netno); } else if(!stricmp(Argv[0],"search")){ // Send UDP Search Command SendUdpBroadcastMsg(); } else if(!stricmp(Argv[0],"auto")){ // Send UDP Search Command if(UcSkt>=0){ bAutoTest=atoi(ptr); if(bAutoTest){ SendTestPattern(); } } } CmdIdx=0; } //------------------------------------------------------------------------------ void DoCmdInput(int data) { if(data==27){ bInCmdMode=0; Puts("{Quit Command Mode}\r\n"); return; } if(data=='\r'){ GetCmd: CmfBuf[CmdIdx]=0; Puts("\r\n"); DoCmd(); ShowPrompt(); } else if(data=='\b'){ if(CmdIdx){ CmdIdx--; Puts("\b \b"); } } else { Putch(data); CmfBuf[CmdIdx++]=data; if(CmdIdx>=MAX_CMD_LEN){ goto GetCmd; } } } //------------------------------------------------------------------------------ void main(int argc,char *argv[]) { int sin_len; int client; int ss; /* slave socket got from accept */ int type, protocol, err=0; int rc; /* return code of selectsocket */ int i; long tt; int datasize,data; int EchoSvr,TcSkt=-1; InitLib(); if(argc>1) { strcpy(RemoteUdpIp,argv[1]); } if(NetStart()) return; bAcceptBroadcast=1; // set to accept broadcast packet. AddUdpPortFilter(57188); AddUdpPortFilter(54321); AddUdpPortFilter(68); AddUdpPortFilter(UdpListenPort); //------------------------------------------------------------------------------ // Client socket. //------------------------------------------------------------------------------ UcSkt = socket( PF_INET, SOCK_DGRAM, 0 ); /* UDP/IP */ if (UcSkt < 0) { Print( "can't create socket! error %d,errno=%d\r\n", UcSkt,errno ); goto End; } if(UdpConnect(255,RemoteUdpIp,RemoteUdpPort)){ Print("connect() failed: %d\r\n", errno); goto End; } EnableUdpBroadcast(UcSkt); //------------------------------------------------------------------------------ // Server socket. //------------------------------------------------------------------------------ #if 1 // UsSkt=UdpListen(255,UdpListenPort); UsSkt=UdpListen(1,UdpListenPort); if (UsSkt < 0) { Print("UDP Listen Error,errno=%d\r\n",errno); } #else UsSkt = socket( PF_INET, SOCK_DGRAM, 0 ); /* UDP/IP */ if (UsSkt < 0) { Print( "can't create socket! error %d,errno=%d\r\n", UsSkt,errno ); goto End; } memset( &sin, 0, sizeof(sin) ); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; // htonl(INADDR_ANY); sin.sin_port = htons( UdpListenPort ); /* bind socket */ if (bind(UsSkt, (struct sockaddr *) &sin, sizeof(sin)) < 0) { /* if this fails, close previously opened ethernet socket and return */ Print("\r\nCan not bind the UDP socket\r\n"); goto End; } #endif if(UsSkt >= 0) EnableUdpBroadcast(UsSkt); //------------------------------------------------------------------------------ Print("UcSkt=%d,UsSkt=%d\r\n",UcSkt,UsSkt); //------------------------------------------------------------------------------ EchoSvr=TcpListen(10000); // EnableWDT(); while(!Quit){ // RefreshWDT(); YIELD(); if(Kbhit()){ data=Getch(); if(bInCmdMode){ DoCmdInput(data); } else { switch(data){ case 27: Quit=1; break; case '/': bInCmdMode=1; CmdIdx=0; ShowPrompt(); break; case '+': SendUdpBroadcastMsg(); break; default: if(UcSkt >= 0){ i = sendto(UcSkt, &data, 1, 0, (struct sockaddr *) &UcSin, sizeof(UcSin)); } break; } } } if( UcSkt>=0 && !ioctlsocket(UcSkt,FIONREAD,&datasize) && (datasize > 0)){ DoUdpClientSocket(); } else { if(bAutoTest){ if(GetTimeTicks()-ttTest >= 100){ SendTestPatternAgain(); } } } if( UsSkt>=0 && !ioctlsocket(UsSkt,FIONREAD,&datasize) && (datasize > 0)){ DoUdpServerSocket(); } if( EchoSvr>=0 && !ioctlsocket(EchoSvr,FIONREAD,&datasize) && (datasize > 0)){ DoEchoServer(EchoSvr,&TcSkt); } if( TcSkt>=0 && !ioctlsocket(TcSkt,FIONREAD,&datasize) && (datasize > 0)){ if(do_echo( TcSkt ) <= 0){ TcSkt=-1; // error, socket is closed. } } } End: DisableWDT(); if(UsSkt>=0) closesocket( UsSkt ); if(UcSkt>=0) closesocket( UcSkt ); if(EchoSvr>=0) closesocket( EchoSvr ); if(TcSkt>=0) closesocket( TcSkt ); Nterm(); }