udp是一種無連線的協議,提供無連線不可靠的服務。
在ace中,通過ACE_SOCK_Dgram類提供udp通訊服務,ACE_SOCK_Dgram和ACE_SOCK_Stream的API非常類似,一樣提供了send,recv及close等常用操作,這裡就不再累述了。
udp通訊時無需像tcp那樣建立連線和關閉連線,tcp程式設計時需要通過accept和connect來建立連線,而udp通訊省略了這一步驟,相對來說程式設計更為簡單。
由於udp通訊時無建立連線,伺服器端不能像Tcp通訊那樣在建立連線的時候就獲得客戶端的地址資訊,故伺服器端不能主動對客戶端傳送資訊(不知道客戶端的地址),只有等到收到客戶端傳送的udp資訊時才能確定客戶端的地址資訊,從而進行通訊。
udp通訊過程如下:
- 伺服器端繫結一固定udp埠,等待接收客戶端的通訊。
- 客戶端通過伺服器的ip和地址資訊直接對伺服器端傳送訊息。
- 伺服器端收到客戶端傳送的訊息後獲取客戶端的ip和埠資訊,通過該地址資訊和客戶端通訊。
下面程式碼為EchoServer的udp版:
//server.cpp
#include <ace/SOCK_Dgram.h>
#include <ace/INET_Addr.h>
#include <ace/Time_Value.h>
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
ACE_INET_Addr port_to_listen(3000); //繫結的埠
ACE_SOCK_Dgram peer(port_to_listen); //通訊通道
char buf[100];
while(true)
{
ACE_INET_Addr remoteAddr; //所連線的遠端地址
int bc = peer.recv(buf,100,remoteAddr); //接收訊息,獲取遠端地址資訊
if( bc != -1)
{
string s(buf,bc);
cout<<endl<<"rev:\t"<<s<<endl;
}
peer.send(buf,bc,remoteAddr); //和遠端地址通訊
}
return 0;
}
相應的客戶端程式如下:
//client.cpp
#include <ace/SOCK_Dgram.h>
#include <ace/INET_Addr.h>
#include <ace/Time_Value.h>
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
ACE_INET_Addr remoteAddr(3000,"127.0.0.1"); //所連線的遠端地址
ACE_INET_Addr localAddr; //本地地址資訊
ACE_SOCK_Dgram peer(localAddr); //通訊通道
peer.send("hello",5,remoteAddr); //傳送訊息
char buf[100];
int bc = peer.recv(buf,100,remoteAddr); //接收訊息
if( bc != -1)
{
string s(buf,bc);
cout<<endl<<"rev:\t"<<s<<endl;
}
return 0;
}
和tcp程式設計相比,udp無需通過acceptor,connector來建立連線,故程式碼相對tcp程式設計來說要簡單許多。另外,由於udp是一種無連線的通訊方式,ACE_SOCK_Dgram的例項物件中無法儲存遠端地址資訊(儲存了本地地址資訊),故通訊的時候需要加上遠端地址資訊。