请教各路高手:进来帮忙给小弟拿个主意!?(100分送!!!)

时间:2021-02-02 16:32:35
现在,小弟要做一个网络通讯方面的毕业设计。
平台:客户使用WINCE,服务器使用Win 2000 Server.
开发环境:VC、embeded VC.
硬件组成:PDA、GPRS/GPS卡、服务器.
主要功能:PDA终端作为测量终端,实时的向服务器(监控中心)发送自己的地理位置信息,服务器端对这些数据进行实时显示、录入等。

现在的问题是:一旦有大量的PDA终端(比如500个)连入的话,服务器端如何保证数据的实时处理哪?又如何保证最大限度的网络通畅哪?

希望过路的大虾出出高招?谢先!!!

12 个解决方案

#1


帮你up一下

#2


建议去企业开发专题GIS

#3


Multithread + Buffer

#4


我自己就是GIS专业的,所以只想听听编程高手们的意思。
因为这个跟网络编程联系还是要大些。

honix,你是说在服务器端采用多线程和读入数据缓冲区吗?我搞不清楚服务器端要绑定几个Socket Server 才比较好呢?就是说同时有多个SocketServer在工作(当连入的客户端比较多的时候)。
另外我个人觉着用基于UDP的数据报Socket是不是比基于流的更适合于这种应用?
就象一些网络游戏,经常要互相发送各自的位置信息。。。

各位高手请多关照,小弟没有接触过这方面的编程,所以并不知道这些接口函数的性能和机制,就不好写规划了,help!

#5


看了MSDN里面的SDK中的例子:
/*
* This is the main function that handles all the events occuring on the
* different handles we are watching.
*
* Parameters:
*          index: Index into the Handles[] array. Returned by DoWait()
*          Handles: Array of Event Handles we are watching
*          socklist: Helper parallel array of state information
*
*/
void HandleEvent(int index, HANDLE *Handles,Socklist *socklist) 
{
OVERLAPPED *Overlap;
SOCKET newsock;
DWORD bytes,overlap_err=0,lasterr;

Overlap = socklist[index].overlap;
//
// Check the specified handle(Event)
//
// If a socket is closed by the other side, the error returned is
// ERROR_NETNAM_DELETED
//
if(!GetOverlappedResult(Handles[index], Overlap, &bytes, TRUE) ) 
{
fprintf(stderr,"GetOverlappedResult failed with error %d\n", overlap_err=GetLastError());
if (overlap_err  != ERROR_NETNAME_DELETED) 
return;
}
newsock = Overlap->Offset;
//
// If the other side closed the connection, close our socket and 
// move the last element of the Handles[] array into our 
// index.

// The array compaction is done so that we only pass valid handles
// in the first "curr_size" elements of the array to
// WaitForMultipleObjects(). The function will fail otherwise.


// We should NEVER get this for our listening socket: index>0!
if (index && overlap_err == ERROR_NETNAME_DELETED) 
{
closesocket(newsock);
xfree(Overlap);
Handles[index] = Handles[curr_size-1];
socklist[index] = socklist[curr_size-1];
curr_size--;
fprintf(stderr,"ERROR_NETNAME_DELETED index/Curr_size:%d /%d. \n",index,curr_size);
return;
}

if( (index ==0) ) //listening socket

fprintf(stderr,"HandelEvent:Listening socket.Now start reading...\n");

if (curr_size >= MAX_IO_PEND) 
{
fprintf(stderr,"Too many pending requests\n");
return;
}
//
// Get the event handle used to queue the AcceptEx(),
// and re-use it to queue a ReadFile on the socket.
//

Handles[curr_size] = Overlap->hEvent;
socklist[curr_size].overlap = Overlap;

//
// The OffsetHigh field is used to keep track of what we are doing.
// This enables us to alternate ReadFile and WriteFile on a 
// connection

Overlap->OffsetHigh = OP_READ;//自己设置成读入.
//开始读:
if (!ReadFile((HANDLE)newsock, socklist[curr_size].Buffer,
sizeof(socklist[curr_size].Buffer),
&bytes,
Overlap) ) 
{
lasterr = GetLastError();

// Handle ERROR_NETNAME_DELETED specially
// Other errors are Not Good
//
if (lasterr && lasterr != ERROR_IO_PENDING &&
lasterr != ERROR_NETNAME_DELETED )
{
fprintf(stderr,"Inital ReadFile failed %d\n");
return;
}
if (lasterr == ERROR_NETNAME_DELETED) 
{
closesocket(newsock);
xfree(Overlap);
Handles[index] = Handles[curr_size];
socklist[index] = socklist[curr_size];
curr_size--;
return;
}
}
//
// Increment the last valid handle location in the Handles
// array.
curr_size++;
fprintf(stderr,"curr_size is %d\n",curr_size);

return;
}//End of listening socket...
//
// This possibly indicates a closed socket.
//
if (  (bytes == 0 ) && (Overlap->OffsetHigh == OP_READ) )
{
closesocket(newsock);
xfree(Overlap);
Handles[index] = Handles[curr_size];
socklist[index] = socklist[curr_size];
curr_size--;
fprintf(stderr,"Socket colsed! index/Curr_size:%d /%d. \n",index,curr_size);
return;
}
//
//  If the previous operation was an OP_READ, queue WriteFile on the
//  socket
//
if (Overlap->OffsetHigh == OP_READ) 
{ // ReadFile was queued
printf("Read buffer [%s],",socklist[index].Buffer);
printf("Echoing back to client\n");
if (!WriteFile((HANDLE)newsock, socklist[index].Buffer,
sizeof(socklist[index].Buffer),
&bytes,
Overlap) ) 
{
lasterr = GetLastError();
if (lasterr && lasterr != ERROR_IO_PENDING &&
lasterr != ERROR_NETNAME_DELETED ) 
{
fprintf(stderr,"WriteFile failed %d\n");
ExitProcess(1);
}
if ( (lasterr == ERROR_NETNAME_DELETED) || (!lasterr)) 
{
closesocket(newsock);
xfree(Overlap);
Handles[index] = Handles[curr_size];
socklist[index] = socklist[curr_size];
curr_size--;
return;
}
}
Overlap->OffsetHigh = OP_WRITE;//queue WriteFile on the newsock( = Overlap->Offset).
return;
}
//
// If we had a WriteFile queued, now do a ReadFile
//
else if (Overlap->OffsetHigh == OP_WRITE) // WriteFile was queued, then readfile

printf("Wrote %d bytes. ",bytes);
printf("Queueing read\n");
if (!ReadFile((HANDLE)newsock, socklist[index].Buffer,
sizeof(socklist[index].Buffer),
&bytes,
Overlap) ) 
{
lasterr =GetLastError();
if (lasterr && lasterr != ERROR_IO_PENDING) 
{
if (lasterr == ERROR_NETNAME_DELETED) 
{
closesocket(newsock);
xfree(Overlap);
Handles[index] = Handles[curr_size];
socklist[index] = socklist[curr_size];
curr_size--;
return;
}
fprintf(stderr,"ReadFile failed %d\n",GetLastError());
ExitProcess(1);
}
}
Overlap->OffsetHigh = OP_READ;
return;
}
else 
{
fprintf(stderr,"Unknown operation queued\n");
}

}
不明白!

#6


这些问题。国内没有好的文章你英语好的可以去国外的站点看看GOOGLE搜

#7


针对WINCE的开发,国内确实没有好的文章,还是到国外站点搜搜!!

#8


多谢,有没有高手去过一些好的网站哪,介绍一下?
谢谢先!
以后等回复多了就结帖。

#9


服务器用IO完成端口,可以应付大规模客户端并发访问。

#10


我想,不同应用中的“实时”含义不同,此处则是实时报告自己的位置,两次报告总有间隔,1秒?3秒?10秒。。。针对大客户量和小数据量,且稳定性要求不严时,采用UDP较好:其一,UDP的稳定性可以接受;其二,省去连接时间,非常重要。在实现中不妨这样:PDA向服务端发送数据,并监听端口,等待回应,如果在较短时间内没有回应,则重复发送;如果收到回应,则作较长延时后,进行下一次报告。相应的在服务端要监听一个端口接收数据,同时用另外一个SOCKET向传来数据的PDA发回应信息。

#11


多谢多谢!
楼上的两位的意见我已经考虑了。
完成端口模型倒是挺不错的!
wangjinwang 所说的采用UDP协议,我也想了一下,由于PDA客户并不是频繁的进行连接(登录的时候建立一个连接,之后除非是由于建筑物或其他的特殊情况导致无线通讯中断,否则是不必重新连接的),所以这样的 UDP 无连接机制和 TCP 连接机制到底谁好,要试过才知道,下去后我先用 TCP试试先!
非常感谢!

#12


好啦!
响应斑竹的号召,结帖!
到时候我会再来这里说说我对该问题的解决方案的。
多谢回帖的朋友!

#1


帮你up一下

#2


建议去企业开发专题GIS

#3


Multithread + Buffer

#4


我自己就是GIS专业的,所以只想听听编程高手们的意思。
因为这个跟网络编程联系还是要大些。

honix,你是说在服务器端采用多线程和读入数据缓冲区吗?我搞不清楚服务器端要绑定几个Socket Server 才比较好呢?就是说同时有多个SocketServer在工作(当连入的客户端比较多的时候)。
另外我个人觉着用基于UDP的数据报Socket是不是比基于流的更适合于这种应用?
就象一些网络游戏,经常要互相发送各自的位置信息。。。

各位高手请多关照,小弟没有接触过这方面的编程,所以并不知道这些接口函数的性能和机制,就不好写规划了,help!

#5


看了MSDN里面的SDK中的例子:
/*
* This is the main function that handles all the events occuring on the
* different handles we are watching.
*
* Parameters:
*          index: Index into the Handles[] array. Returned by DoWait()
*          Handles: Array of Event Handles we are watching
*          socklist: Helper parallel array of state information
*
*/
void HandleEvent(int index, HANDLE *Handles,Socklist *socklist) 
{
OVERLAPPED *Overlap;
SOCKET newsock;
DWORD bytes,overlap_err=0,lasterr;

Overlap = socklist[index].overlap;
//
// Check the specified handle(Event)
//
// If a socket is closed by the other side, the error returned is
// ERROR_NETNAM_DELETED
//
if(!GetOverlappedResult(Handles[index], Overlap, &bytes, TRUE) ) 
{
fprintf(stderr,"GetOverlappedResult failed with error %d\n", overlap_err=GetLastError());
if (overlap_err  != ERROR_NETNAME_DELETED) 
return;
}
newsock = Overlap->Offset;
//
// If the other side closed the connection, close our socket and 
// move the last element of the Handles[] array into our 
// index.

// The array compaction is done so that we only pass valid handles
// in the first "curr_size" elements of the array to
// WaitForMultipleObjects(). The function will fail otherwise.


// We should NEVER get this for our listening socket: index>0!
if (index && overlap_err == ERROR_NETNAME_DELETED) 
{
closesocket(newsock);
xfree(Overlap);
Handles[index] = Handles[curr_size-1];
socklist[index] = socklist[curr_size-1];
curr_size--;
fprintf(stderr,"ERROR_NETNAME_DELETED index/Curr_size:%d /%d. \n",index,curr_size);
return;
}

if( (index ==0) ) //listening socket

fprintf(stderr,"HandelEvent:Listening socket.Now start reading...\n");

if (curr_size >= MAX_IO_PEND) 
{
fprintf(stderr,"Too many pending requests\n");
return;
}
//
// Get the event handle used to queue the AcceptEx(),
// and re-use it to queue a ReadFile on the socket.
//

Handles[curr_size] = Overlap->hEvent;
socklist[curr_size].overlap = Overlap;

//
// The OffsetHigh field is used to keep track of what we are doing.
// This enables us to alternate ReadFile and WriteFile on a 
// connection

Overlap->OffsetHigh = OP_READ;//自己设置成读入.
//开始读:
if (!ReadFile((HANDLE)newsock, socklist[curr_size].Buffer,
sizeof(socklist[curr_size].Buffer),
&bytes,
Overlap) ) 
{
lasterr = GetLastError();

// Handle ERROR_NETNAME_DELETED specially
// Other errors are Not Good
//
if (lasterr && lasterr != ERROR_IO_PENDING &&
lasterr != ERROR_NETNAME_DELETED )
{
fprintf(stderr,"Inital ReadFile failed %d\n");
return;
}
if (lasterr == ERROR_NETNAME_DELETED) 
{
closesocket(newsock);
xfree(Overlap);
Handles[index] = Handles[curr_size];
socklist[index] = socklist[curr_size];
curr_size--;
return;
}
}
//
// Increment the last valid handle location in the Handles
// array.
curr_size++;
fprintf(stderr,"curr_size is %d\n",curr_size);

return;
}//End of listening socket...
//
// This possibly indicates a closed socket.
//
if (  (bytes == 0 ) && (Overlap->OffsetHigh == OP_READ) )
{
closesocket(newsock);
xfree(Overlap);
Handles[index] = Handles[curr_size];
socklist[index] = socklist[curr_size];
curr_size--;
fprintf(stderr,"Socket colsed! index/Curr_size:%d /%d. \n",index,curr_size);
return;
}
//
//  If the previous operation was an OP_READ, queue WriteFile on the
//  socket
//
if (Overlap->OffsetHigh == OP_READ) 
{ // ReadFile was queued
printf("Read buffer [%s],",socklist[index].Buffer);
printf("Echoing back to client\n");
if (!WriteFile((HANDLE)newsock, socklist[index].Buffer,
sizeof(socklist[index].Buffer),
&bytes,
Overlap) ) 
{
lasterr = GetLastError();
if (lasterr && lasterr != ERROR_IO_PENDING &&
lasterr != ERROR_NETNAME_DELETED ) 
{
fprintf(stderr,"WriteFile failed %d\n");
ExitProcess(1);
}
if ( (lasterr == ERROR_NETNAME_DELETED) || (!lasterr)) 
{
closesocket(newsock);
xfree(Overlap);
Handles[index] = Handles[curr_size];
socklist[index] = socklist[curr_size];
curr_size--;
return;
}
}
Overlap->OffsetHigh = OP_WRITE;//queue WriteFile on the newsock( = Overlap->Offset).
return;
}
//
// If we had a WriteFile queued, now do a ReadFile
//
else if (Overlap->OffsetHigh == OP_WRITE) // WriteFile was queued, then readfile

printf("Wrote %d bytes. ",bytes);
printf("Queueing read\n");
if (!ReadFile((HANDLE)newsock, socklist[index].Buffer,
sizeof(socklist[index].Buffer),
&bytes,
Overlap) ) 
{
lasterr =GetLastError();
if (lasterr && lasterr != ERROR_IO_PENDING) 
{
if (lasterr == ERROR_NETNAME_DELETED) 
{
closesocket(newsock);
xfree(Overlap);
Handles[index] = Handles[curr_size];
socklist[index] = socklist[curr_size];
curr_size--;
return;
}
fprintf(stderr,"ReadFile failed %d\n",GetLastError());
ExitProcess(1);
}
}
Overlap->OffsetHigh = OP_READ;
return;
}
else 
{
fprintf(stderr,"Unknown operation queued\n");
}

}
不明白!

#6


这些问题。国内没有好的文章你英语好的可以去国外的站点看看GOOGLE搜

#7


针对WINCE的开发,国内确实没有好的文章,还是到国外站点搜搜!!

#8


多谢,有没有高手去过一些好的网站哪,介绍一下?
谢谢先!
以后等回复多了就结帖。

#9


服务器用IO完成端口,可以应付大规模客户端并发访问。

#10


我想,不同应用中的“实时”含义不同,此处则是实时报告自己的位置,两次报告总有间隔,1秒?3秒?10秒。。。针对大客户量和小数据量,且稳定性要求不严时,采用UDP较好:其一,UDP的稳定性可以接受;其二,省去连接时间,非常重要。在实现中不妨这样:PDA向服务端发送数据,并监听端口,等待回应,如果在较短时间内没有回应,则重复发送;如果收到回应,则作较长延时后,进行下一次报告。相应的在服务端要监听一个端口接收数据,同时用另外一个SOCKET向传来数据的PDA发回应信息。

#11


多谢多谢!
楼上的两位的意见我已经考虑了。
完成端口模型倒是挺不错的!
wangjinwang 所说的采用UDP协议,我也想了一下,由于PDA客户并不是频繁的进行连接(登录的时候建立一个连接,之后除非是由于建筑物或其他的特殊情况导致无线通讯中断,否则是不必重新连接的),所以这样的 UDP 无连接机制和 TCP 连接机制到底谁好,要试过才知道,下去后我先用 TCP试试先!
非常感谢!

#12


好啦!
响应斑竹的号召,结帖!
到时候我会再来这里说说我对该问题的解决方案的。
多谢回帖的朋友!