這里向用(yong)戶介紹一個(ge)讓(rang)ZLIP同時處理4個(ge)TCP連(lian)接(2個(ge)客戶端、2個(ge)服務(wu)器端)、兩個(ge)UDP連(lian)接和PING的(de)程序。該演(yan)示將讓(rang)用(yong)戶初步了(le)解ZLIP的(de)功能(neng)。
按照開發運行新程序一節的(de)步驟(zou)將UseZLIPLib下載(zai)到開發板中。
1. 打開sscomv2.0,波特率為19200;重新打開開發板電源,串口顯示:
test_complex_send_recv test...
TODO: listen at 192.168.0.3:1024, and press key
press any key...
按以上要求讓SocketTestDlg在TCP1024端口監聽,然后向串口發送一個任意字符,作為“press key”。

串口和SocketTestDlg提示信息表明開發板向PC機發起了兩個連接并建立了兩個連接。
2. 發送文件:由于發送文件需要較長時間,需要再運行一個SocketTestDlg程序,并使用Client Connect向192.168.0.2:1024發起連接。

串口輸出和SocketTestDlg提示信息表明連接建立。SocketTestDlg中的send file選擇為“\工具\SocketTestDlg\send_test_file\1_75M”,Send
Mode選擇Send File。點擊ClientSend 開始發送文件。
3. 采用ping 192.168.0.2 –t,PING開發板。

4. 做如下的操作(為了演示ZLIP的同時處理多個連接的能力,以下操作在上面的數據發送和PING同時進行):
(1) 采用ServerSend向板子發送“a”字符,串口顯示“sc0 a”和“sc1 a”表明板子上的兩個TCP客戶端都收到數據“a”。

(2) 采用ClienConnect向板子的192.168.0.2:1024發起連接,可建立連接。串口顯示“lisen 1 accept”,表明連接建立。連接建立以后采用ClientSend發送“b”,服務器端將收到回饋數據“b”。
(3) SocketTestDlg創建UDP后,向UDP 192.168.0.2:1024和UDP 192.168.0.2:1025分別發送“c和發送“d”字符,串口顯示“su0
recv2:c”和“su1 recv2:d”表明板子上的兩個UDP實例也收到了數據。
5. 當第二步“發送文件”完成后,點擊ClientClose關閉連接,此時串口和SocketTestDlg提示消息如下:

圖中顯示了接收方(串口顯示的數據)和發送方(SocketTestDlg顯示的數據)的數據校驗和一致,表明發送數據無誤。
在該演示例子中,演示了ZLIP同時處理4個TCP連接(2個作為客戶端、2個作為服務器端)、兩個UDP連接和PING功能的能力。
以(yi)上例子的(de)代碼如下(該代碼讀者可稍作了解,詳細(xi)的(de)分析需參(can)考Socket API):
void test_complex_send_recv()
{
/* 2 listen, 2 connect, 4 accpeted 2 udp,
and ping same time
server:
listen and send any data
connect and send big data
connect to 1025, 1024 at any time.
send any data to udp port
ping all the time.*/
SOCKET sl[2], sc[2], sa[4], su[2];
struct sockaddr_in src_addr, dest_addr, get_addr;
fd_set r, w;
zl_u32 len, val;
int accept_cnt, i, j;
int sc0_conn=FALSE, sc1_conn=FALSE;
int ret;
zl_u32 total_recv=0;
zl_u32 file_sum = 0;
zl_u8 c=0;
printf("\ntest_complex_send_recv test...");
if((sl[0] = socket(PF_INET, SOCK_STREAM, 0))
== SOCK_ERR)
return;
if((sl[1] = socket(PF_INET, SOCK_STREAM, 0))
== SOCK_ERR)
return;
if((sc[0] = socket(PF_INET, SOCK_STREAM, 0))
== SOCK_ERR)
return;
if((sc[1] = socket(PF_INET, SOCK_STREAM, 0))
== SOCK_ERR)
return;
if((su[0] = socket(PF_INET, SOCK_DGRAM, 0))
== SOCK_ERR)
return;
if((su[1] = socket(PF_INET, SOCK_DGRAM, 0))
== SOCK_ERR)
return;
/* listen */
src_addr.sin_addr = IPAddr;
src_addr.sin_port = 1024;
dest_addr.sin_addr = DestIP;
dest_addr.sin_port = 1024;
len = sizeof(struct sockaddr_in);
printf("\nTODO: listen at %s:%d, and
press key",inet_ntoa(&dest_addr),dest_addr.sin_port);
wait_key();
printf("\nTODO: do any of the following
action, even at same time( if any socket closed by peer exit):"
"\n1. Peer listen
socket send any data to us."
"\n2. peer connect
to %s:%d or 1025 at any time (max two socket, NOTE by two TestSocket
app)and send big data."
"\n3. send any
UDP data to udp %s:%d or 1025."
"\n4. ping at
any time.",inet_ntoa(&src_addr),src_addr.sin_port,inet_ntoa(&src_addr),src_addr.sin_port);
printf("\nEXPECT: print \"sc0 and
sc1 connection establish\", and correspond to each action:"
"\n1. print \"s0
or s1 receive\" and peer receive the data sent"
"\n2. print \"listen
accept\". print \"sa receive\". print the result and
len of file sent by connection 0, peer will receive
some data from sa[0] for every receive;sa[1] will send what received."
"\n3. print \"su0
or su1 recevie data\" and peer receive the same data"
"\n4. ping success.");
/* listen and udp */
if(bind(sl[0], &src_addr, len) == SOCK_ERR)
return;
if(bind(su[0], &src_addr, len) == SOCK_ERR)
return;
src_addr.sin_port = 1025;
if(bind(sl[1], &src_addr, len) == SOCK_ERR)
return;
if(bind(su[1], &src_addr, len) == SOCK_ERR)
return;
listen(sl[0], 0);
listen(sl[1], 0);
/* connect in nonblock */
val = TRUE;
ioctlsocket(sc[0], FIONBIO, &val);
val = TRUE;
ioctlsocket(sc[1], FIONBIO, &val);
connect(sc[0], &dest_addr, len);
connect(sc[1], &dest_addr, len);
accept_cnt = 0;
while(TRUE)
{
FD_ZERO(&r);
FD_ZERO(&w);
FD_SET(sl[0], &r);
FD_SET(sl[1], &r);
FD_SET(su[0], &r);
FD_SET(su[1], &r);
if(sc0_conn == FALSE)
FD_SET(sc[0],
&w);
/* it can be read,
if connection fail */
FD_SET(sc[0], &r);
if(sc1_conn == FALSE)
FD_SET(sc[1],
&w);
FD_SET(sc[1], &r);
for(i = 0; i< accept_cnt;
i++)
FD_SET(sa[i],
&r);
select(0, &r,
&w, NULL, NULL);
/* check accept sl[0]*/
if(FD_ISSET(sl[0],
&r))
{
printf("\nlisten
0 accept");
len
= sizeof(struct sockaddr_in);
if((sa[accept_cnt++]
= accept(sl[0], &dest_addr, &len)) == SOCK_ERR)
{
printf("accept
error!");
accept_cnt--;
}
}
/* check accept sl[1]*/
if(FD_ISSET(sl[1],
&r))
{
printf("\nlisten
1 accept");
len
= sizeof(struct sockaddr_in);
if((sa[accept_cnt++]
= accept(sl[1], &dest_addr, &len)) == SOCK_ERR)
{
printf("accept
error!");
accept_cnt--;
}
}
/* check nonblock
connection stablish */
if(FD_ISSET(sc[0],
&w))
{
printf("\nsc
0 connection establish");
sc0_conn
= TRUE;
}
if(FD_ISSET(sc[1],
&w))
{
printf("\nsc
1 connection establish");
sc1_conn
= TRUE;
}
/* check peer listen
socket send data */
if(FD_ISSET(sc[0],
&r))
{
ret
= recv(sc[0], DataBlockBIG, DATA_SIZE_BIG, MSG_RECV_NORMAL);
send(sc[0],
DataBlockBIG, ret, 0);
if(ret
== 0)
{
printf("\nsocket
colsed by peer!");
break;
}
else
{
printf("sc0
%s ",DataBlockBIG);
}
}
if(FD_ISSET(sc[1],
&r))
{
ret
= recv(sc[1], DataBlockBIG, DATA_SIZE_BIG, MSG_RECV_NORMAL);
send(sc[1],
DataBlockBIG, ret, 0);
if(ret
== 0)
{
printf("\nsocket
colsed by peer!");
break;
}
else
{
printf("sc1
%s ",DataBlockBIG);
}
}
/* check upd socket
recv data */
if(FD_ISSET(su[0],
&r))
{
len
= sizeof(struct sockaddr_in);
ret
= recvfrom(su[0], DataBlockBIG, DATA_SIZE_BIG, MSG_RECV_NORMAL,
&get_addr,
&len);
printf("su0
recv%d: %s ",ret, DataBlockBIG);
sendto(su[0],
DataBlockBIG, ret, 0, &get_addr, len);
}
if(FD_ISSET(su[1],
&r))
{
len = sizeof(struct sockaddr_in);
ret
= recvfrom(su[1], DataBlockBIG, DATA_SIZE_BIG, MSG_RECV_NORMAL,
&get_addr,
&len);
printf("su1
recv%d: %s ",ret, DataBlockBIG);
sendto(su[1],
DataBlockBIG, ret, 0, &get_addr, len);
}
for(i = 0; i< accept_cnt;
i++)
{
if(FD_ISSET(sa[i],
&r))
{
//printf("sa%d
recv ",i);
ret
= recv(sa[i], DataBlockBIG, DATA_SIZE_BIG, MSG_RECV_NORMAL);
if(ret
== 0)
{
printf("\nsocket
colsed by peer!");
break;
}
/*
only sum what sa 0 received */
else
if(i == 0)
{
for(j
= 0; j<ret; j++)
{
file_sum
+= ((zl_u32)DataBlockBIG[j]-(zl_u32)(c>>(DataBlockBIG[j]&7)));
c
= DataBlockBIG[j];
}
total_recv
+= (zl_u32)ret;
//printf(".%ld.",total_recv);
}
else
{
send(sa[i],DataBlockBIG,ret,0);
}
}
}
if(i!=accept_cnt)
break;
}
socketclose(sl[0]);
socketclose(sl[1]);
socketclose(sc[0]);
socketclose(sc[1]);
socketclose(su[0]);
socketclose(su[1]);
for(i = 0; i<accept_cnt; i++)
{
socketclose(sa[i]);
}
printf("\nresult= %lu,file len= %ld ,
please check it!", file_sum,total_recv);
}
int main(void)
{
/* this devRTL will be used in tcp/ip, pointed
by NetIf->Info */
struct zlip_addr_info DT_XDATA addr_info=
{
ETHER_ADDR,
IPAddr,
NetMask,
GateWay
};
/*
* init
*/
ZLIP_Init(&addr_info);
test_complex_send_recv();
ZLIP_Release();
/*
* release
*/
while(TRUE);
return TRUE;
}