/* ******************************** DEMO1: TCP/IP socket demo File name: demo1.c Compiler: Borland C++ 3.1 Compile mode: large It can help user to write a erch server .user can use clinet program to conect to server using both dual Ethernet . It can create max 32 Client program to connect with server. ********************************* */ #include #include #include #include "module.h" //------------------------------------------------------------------------------ // option //------------------------------------------------------------------------------ #define USE_DHCP 0 //------------------------------------------------------------------------------ #define BUFSIZE 1460 /* read/write buffer size */ #define SERVICE 10000 /* define the service port for Server */ #define SOCKETS NCONNS /* define the maximum number of sockets */ //#define QLEN SOCKETS-1 /* maximum connection queue length */ #define QLEN 1 unsigned long LAST_DAT1; unsigned char snd_buf1[200],snd_buf[200]; static int snd_buf_ind,snd_buf_ind1; static int snd_flag = 0; int es; /* flag to run ES (service loop) */ fd_set rfds; /* set of socket file descriptors for reading */ unsigned char sst[SOCKETS]; int RxCounter=0; int RxCounterOut=0; #if 1 struct ip host_0 = { {192,168,99,99},{255,255,255,0}}; struct ip host_1 = { {10,0,9,232},{255,255,255,0}}; struct ip *host_ip[2]={&host_0,&host_1}; struct ip gateway_0 = { {192,168,99,1},{255,255,255,0}}; struct ip gateway_1 = { {10,0,9,254},{255,255,255,0}}; struct ip *gateway_ip[2]={&gateway_0,&gateway_1}; extern struct NETDATA *NetHost[2],*NetGateway[2]; #else struct ip host_ip = { {192,168,255,2},{255,255,0,0} }; extern struct NETDATA *NetHost,*NetGateway; #endif #define ESTABLISHED 1 /* state machine states, see handbook */ #define FINWAIT_1 2 #define FINWAIT_2 3 #define CLOSED_WAIT 4 #define TIMEWAIT 5 #define LAST_ACK 6 #define CLOSED 7 #define SYN_SENT 8 #define SYN_RECEIVED 9 #define LISTEN 16 void ShowSocketStatus(void) { int i; Puts("\r\n"); for(i=0;i 0 //bUseDhcp=0; //bUseDhcp=0x01; // only net 1 using DHCP client bUseDhcp=0x10; // only net 2 using DHCP client //bUseDhcp=0x11; // both net using DHCP client if(bUseDhcp) Install_DHCP(); // for using DHCP client must call Install_DHCP(); #endif //>>[2008/03/19] err=NetStart(); if(err){ Print("NetStar error=%d\r\n",err); return; } //<<[2008/03/19] // show current IP/MASK/GATEWAY for(i=0;i<2;i++){ Print("net%d:IP=%d.%d.%d.%d, MASK=%d.%d.%d.%d,GATEWAY=%d.%d.%d.%d\r\n",i, netdata[i*2+1].Iaddr.c[0],netdata[i*2+1].Iaddr.c[1], netdata[i*2+1].Iaddr.c[2],netdata[i*2+1].Iaddr.c[3], netdata[i*2+1].Imask.c[0],netdata[i*2+1].Imask.c[1], netdata[i*2+1].Imask.c[2],netdata[i*2+1].Imask.c[3], netdata[i*2].Iaddr.c[0],netdata[i*2].Iaddr.c[1], netdata[i*2].Iaddr.c[2],netdata[i*2].Iaddr.c[3] ); } //>>[2008/03/19] /************************** * allocate master socket * **************************/ Server_Listen: type = SOCK_STREAM; /* TCP/IP */ protocol = 0; /* always 0 */ err = s = socket( PF_INET, type, protocol ); if (s < 0) { Print( "can't create socket! error %d\r\n", err ); goto End; } else Print("Server socket is %d\r\n",s); /******************************** * 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; /* INADDR_ANY is a 32bits zero value */ ssin.sin_addr.s_addr = *(long *)netdata[1].Iaddr.c; ssin.sin_port = htons( SERVICE ); /******************* * bind the socket * *******************/ err = bind( s, (struct sockaddr *)&ssin, sizeof(ssin) ); if (err < 0) { Print( "can't bind to port %d, error %d,errno=%d\r\n", SERVICE, err ,errno); closesocket( s ); goto End; } /****************** * make listening * ******************/ err = listen( s, QLEN ); if (type == SOCK_STREAM && err < 0) { closesocket( s ); } Print("Listen socket=%d, NET=%d\r\n",s,connblo[s].netno); /********** * select * **********/ FD_ZERO( &rfds ); es = 1; for (i = 0; i < SOCKETS; i++) { sst[i] = 0; } sin_len = sizeof( ssin ); while (es) { /* service loop */ // check listen socket. // Method 2: use ioctlsocket(), need add call YIELD(). YIELD(); //[2007/04/26] if (!ioctlsocket(s,FIONREAD, &err) && (err > 0)) { #if QLEN == 0 Print("[socket %d receive DATA]\r\n",s); if(do_echo( s )<=0){ //error or socket is closed; //Listen again goto Server_Listen; } #else Print("new client connect in\r\n"); memset( &ssin, 0, sizeof(ssin) ); err = ss = accept( s, (struct sockaddr *)&ssin, &sin_len ); if (err < 0){ Print( "accept error %d\r\n", err ); break; } if(connblo[ss].netno == 0){ // only accept connection come from NET 0 ip=(unsigned char *)&ssin.sin_addr.s_addr; Print("new connected socket=%d:\r\nIP=%d.%d.%d.%d:%u,NET=%d\r\n",ss, ip[0],ip[1],ip[2],ip[3],SwapShort(ssin.sin_port),connblo[ss].netno ); err=send( ss, Message1, strlen(Message1), 0 ); sst[ss] = 1; //struct CONNECT *conp; //conp = &connblo[s]; connblo[ss].txstat |= S_KEEPA; } else { closesocket(ss); } #endif } // check connected client socket. for (i = 0; i < SOCKETS; i++) { /* scan all possible sockets */ if(sst[i]){ int datasize; if(!ioctlsocket(i,FIONREAD,&datasize) && (datasize > 0)){ if(do_echo( i ) <= 0){ sst[i]=0; // socket is closed } } } } if(Kbhit()){ int data; data=Getch(); if(data==27) break; else if(data=='s'){ ShowSocketStatus(); } } } /* service loop */ killsockets(); End: Nterm(); }