您的位置:首页 > 理论基础 > 计算机网络

2 C++ ACE 基本IO对象 TCP/UDP/HTTP的Server/Client 组播广播

2016-10-31 21:30 471 查看
2 C++ ACE 基本IO对象 TCP/UDP/HTTP的Server/Client 组播广播

ACE I/O相关对象

阻塞式 TCP连接Linux Kernel网站服务器的443端口

非阻塞模式 TCP连接百度服务器

设置 TCP连接超时:

ACE 客户端 TCP模式.请求HTTP

一个简单的 TCP HTTP server
HTTP server 代码
创建网页文件
浏览器测试访问结果

ACE UDP通信单播测试:
UDP 单播 服务器端:
UDP 单播 客户端:

ACE UDP 多播实验:
UDP 多播 发送端程序:
UDP 多播 接收端程序:

UDP 广播实验
UDP 广播发送端
UDP 广播接收端


阻塞式 TCP连接Linux Kernel网站服务器的443端口
chunli@linux:~$ cat main.cpp
#include <iostream>
#include <ace/INET_Addr.h>
#include <ace/SOCK_Connector.h>
#include <ace/SOCK_Stream.h>
int main(void)
{
ACE_SOCK_Connector connector;
ACE_SOCK_Stream peer;
ACE_INET_Addr peerAddr;

if(peerAddr.set(443,"www.kernel.org") == -1)
{
std::cerr << "peerAddr.set set error\n";
return -1;
}
else if(connector.connect(peer,peerAddr) == -1)
{
std::cerr << "connector.connect error\n";
return -1;
}
std::cout << "Hello ACE\n";
return 0;
}
chunli@linux:~$ g++ -Wall main.cpp -l ACE && ./a.out
Hello ACE
chunli@linux:~$


非阻塞模式 TCP连接百度服务器
chunli@linux:~$ cat main.cpp
#include <iostream>
#include <ace/INET_Addr.h>
#include <ace/SOCK_Connector.h>
#include <ace/SOCK_Stream.h>
int main(void)
{
ACE_SOCK_Connector connector;
ACE_SOCK_Stream peer;
ACE_INET_Addr peerAddr;

if(peerAddr.set(443,"www.baidu.com") == -1)
{
std::cerr << "peerAddr.set set error\n";
return -1;
}
if(connector.connect(peer,peerAddr,&ACE_Time_Value::zero) == -1)//传一个时间指针,时间是0,不需要等
{
if(errno == EWOULDBLOCK)//如果不能设置为非阻塞
{
std::cerr << "不能设置为非阻塞\n";
}
if(connector.connect(peer,0,&ACE_Time_Value::zero) == -1)
{
std::cerr << "connector.connect error\n";
}
else
{
std::cout << "Hello ACE\n";
}
}
else
{
std::cout << "Hello ACE\n";
}

return 0;
}
chunli@linux:~$ g++ -Wall main.cpp -l ACE && ./a.out
不能设置为非阻塞
connector.connect error
chunli@linux:~$


设置 TCP连接超时:
chunli@linux:~$ cat main.cpp
#include <iostream>
#include <ace/INET_Addr.h>
#include <ace/SOCK_Connector.h>
#include <ace/SOCK_Stream.h>
int main(void)
{
ACE_SOCK_Connector connector;
ACE_SOCK_Stream peer;
ACE_INET_Addr peerAddr;
ACE_Time_Value timeout(1);	//超时设置

if(peerAddr.set(443,"www.baidu.com") == -1)
{
std::cerr << "peerAddr.set set error\n";
return -1;
}
if(connector.connect(peer,peerAddr,&timeout) == -1)//传一个时间指针,时间是0,不需要等
{
if(errno == ETIME)
{
std::cerr << " 连接超时\n";
}
}
else
{
std::cout << "Hello ACE\n";
}
return 0;
}
chunli@linux:~$ g++ -Wall main.cpp -l ACE && ./a.out
Hello ACE
chunli@linux:~$


ACE 客户端 TCP模式.请求HTTP
chunli@linux:~/ACE$ cat main.cpp
#include <iostream>
#include <ace/INET_Addr.h>
#include <ace/SOCK_Connector.h>
#include <ace/SOCK_Stream.h>
#include <ace/Log_Msg.h>
int main(void)
{
ACE_SOCK_Connector connector;
ACE_SOCK_Stream peer;
ACE_INET_Addr peerAddr;

if(peerAddr.set(443,"www.baidu.com") == -1)
{
ACE_ERROR_RETURN((LM_ERROR,"%p\n","set()"),1);
}
else if(connector.connect(peer,peerAddr) == -1)
{
ACE_ERROR_RETURN((LM_ERROR,"%p\n","connect()"),1);
}
char buf[BUFSIZ];	//BUFSIZ 8192
iovec iov[3];
iov[0].iov_base = (char*) "GET";
iov[0].iov_len = 4;
iov[1].iov_base = (char*) "/index.php";
iov[1].iov_len = 10;
//iov[2].iov_base = (char*) "HTTP/1.0\r\n\r\n";
iov[2].iov_base = (char*) "HTTP/1.0";
iov[2].iov_len = 13;
if(peer.sendv_n(iov,3) == -1)
{
ACE_ERROR_RETURN((LM_ERROR,"%p\n","sendv_n()"),1);
}
ssize_t n;
while((n = peer.recv(buf,sizeof(buf))) > 0 )
{
ACE::write_n(ACE_STDOUT,buf,n);
}
return peer.close();
}
chunli@linux:~/ACE$

编译运行:
chunli@linux:~/ACE$
chunli@linux:~/ACE$ g++ main.cpp -l ACE -Wall && ./a.out
HTTP/1.1 302 Moved Temporarily
Server: bfe/1.0.8.18
Date: Fri, 28 Oct 2016 12:55:54 GMT
Content-Type: text/html
Content-Length: 17931
Connection: close
ETag: "54d9748e-460b"

<html>
<head>
<div id="content_left">
<div class="nors">
<div class="norsSuggest">
<h3 class="norsTitle">很抱歉,您要访问的页面不存在!</h3>
<p class="norsTitle2">温馨提示:</p>
<ol>
<li>请检查您访问的网址是否正确</li>
<li>如果您不能确认访问的网址,请浏览<a href="http://www.baidu.com/more/index.html">百度更多</a>页面查看更多网址。</li>
<li>回到顶部重新发起搜索</li>
<li>如有任何意见或建议,请及时<a href="http://qingting.baidu.com/index">反馈给我们</a>。</li>

</ol>
</div>
</div>
</div>


一个简单的 TCP HTTP server
chunli@linux:~/ACE$ cat main.cpp
#include <string.h>

#include <ace/INET_Addr.h>
#include <ace/SOCK_Acceptor.h>
#include <ace/SOCK_Stream.h>
#include <ace/Mem_Map.h>
#include <ace/Log_Msg.h>

extern char *get_url_pathname(ACE_SOCK_Stream *);

int main(void)
{
ACE_INET_Addr 		server_addr;
ACE_SOCK_Acceptor 	acceptor;
ACE_SOCK_Stream 	peer;
if(server_addr.set(11223) == -1)//监听端口随意选,有些端口需要root权限才可以
{
ACE_ERROR_RETURN((LM_ERROR,"%p\n","set()"),1);
}
if(acceptor.open(server_addr) == -1)
{
ACE_ERROR_RETURN((LM_ERROR,"%p\n","open()"),1);
}
while(1)
{
if(acceptor.accept(peer) == -1)
{
ACE_ERROR_RETURN((LM_ERROR,"%p\n","accept()"),1);
}
peer.disable(ACE_NONBLOCK);
char * pathname = get_url_pathname(&peer);
if(pathname == NULL)
{
ACE_ERROR_RETURN((LM_ERROR,"%p\n","get_url_pathname()"),1);
}
ACE_Mem_Map mapped_file(pathname);
delete [] pathname;
if(peer.send_n(mapped_file.addr(),mapped_file.size()) == -1)
{
ACE_ERROR_RETURN((LM_ERROR,"%p\n","send_n()"),1);
}
peer.close();
}
return acceptor.close() == -1?1:0;
}

char* get_url_pathname(ACE_SOCK_Stream* peer)
{
static const char * docBase = "./pages";
char buf[512];
if(peer->recv(buf,sizeof(buf)) != -1)
{
// request example:
// GET /index.html HTTP/1.0\r\n
const char *pos1 = strchr(buf,' ');
const char *pos2 = strchr(++pos1,' ');
const size_t len = pos2 - pos1;
const size_t docLen = strlen(docBase);
char* path = new char [len + docLen +1];
memcpy(path,docBase,docLen);
memcpy(path+docLen,pos1,len);
return path;
}
return NULL;
}

既然是一个HTTP服务器,那么我得准备网页文件:
创建网页文件:
chunli@linux:~/ACE$ cat pages/hello.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>标题文字</title>
</head>
<body >
<h1> 测试啊.....................</h1>
</body>
</html>
chunli@linux:~/ACE$

编译运行:
chunli@linux:~/ACE$ g++ main.cpp -l ACE -Wall && ./a.out

另开窗口查看监听:
chunli@linux:/tmp$ netstat -tnlpa  | grep 11223
tcp        0      0 0.0.0.0:11223           0.0.0.0:*               LISTEN      2060/a.out

浏览器测试访问结果:
chunli@linux:/tmp$ curl  localhost:11223/hello.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>标题文字</title>
</head>
<body >
<h1> 测试啊.....................</h1>
</body>
</html>
chunli@linux:/tmp$
实验完毕!


ACE UDP通信单播测试

UDP 单播 服务器端:
chunli@linux:~/ACE$ cat udp_server.cpp
/*****************************************************************
功能:ACE UDP server
描述:使用ACE网络库,实现简单的UDP服务器程序,监听在本机的8080端口
作者:魂斗罗
日期:2016.10.29
邮箱:li_chunli@mail.com
版本:1.0
******************************************************************/
#include <string.h>
#include <ace/INET_Addr.h>
#include <ace/SOCK_Dgram.h>
#include <ace/Time_Value.h>
#include <ace/Log_Msg.h>

int main(int agrc,char** argv)
{
ACE_INET_Addr 		serverAddr(8080);
ACE_SOCK_Dgram		peer(serverAddr);
char buf[BUFSIZ];
while(1)
{
memset(buf,0,BUFSIZ);
ACE_INET_Addr	remoteAddr;
size_t	len = peer.recv(buf,BUFSIZ,remoteAddr);
if(len > 0)
{
peer.send(buf,BUFSIZ,remoteAddr);
ACE_DEBUG((LM_DEBUG,"%s %s \n","recv",buf));
}
}
}
chunli@linux:~/ACE$

服务器编译运行:
chunli@linux:~/ACE$ g++ udp_server.cpp -l ACE -Wall && ./a.out
recv hello ACE
recv 中文测试
^C
chunli@linux:~/ACE$


UDP 单播 客户端:
UDP 单播 客户端:

chunli@linux:~/ACE$ cat udp_client.cpp
/*****************************************************************
功能:ACE UDP client
描述:使用ACE网络库,实现简单的UDP客户端程序,向远程主机的8080端口发数据
作者:魂斗罗
日期:2016.10.29
邮箱:li_chunli@mail.com
版本:1.0
******************************************************************/
#include <string.h>
#include <iostream>
#include <ace/INET_Addr.h>
#include <ace/SOCK_Dgram.h>
#include <ace/Time_Value.h>
#include <ace/Log_Msg.h>

int main(int agrc,char** argv)
{
ACE_INET_Addr           remoteAddr(8080,"11.11.11.6");
ACE_INET_Addr           localAddr;
ACE_SOCK_Dgram          peer(localAddr);
char buf[BUFSIZ];
while(1)
{
memset(buf,0,BUFSIZ);
std::cin.getline(buf,BUFSIZ);
if(0 == strcmp("quit",buf))
{
break;
}
ssize_t len = peer.send(buf,strlen(buf),remoteAddr);
if(len > 0)
{
ACE_DEBUG((LM_DEBUG,"%s \n",buf));
}
}
return 0;
}
chunli@linux:~/ACE$

客户端编译运行:
chunli@linux:~/ACE$ g++ udp_client.cpp -l ACE -Wall  -o client && ./client
hello ACE
hello ACE
中文测试
中文测试
^C
chunli@linux:~/ACE$


ACE UDP 多播实验:
UDP 多播 发送端程序:
chunli@linux:~/ACE$ cat udp_mulitcast_send.cpp
/*****************************************************************
功能:ACE UDP 多播 发送端
描述:使用ACE网络库,实现简单的UDP ,读取键盘,多播发送
作者:魂斗罗
日期:2016.10.29
邮箱:li_chunli@mail.com
版本:1.0
******************************************************************/
#include <iostream>
#include <ace/SOCK_Dgram_Mcast.h>
#include <ace/Log_Msg.h>
int main(int argc,char ** argv)
{
ACE_INET_Addr		mcastAddr(9988,"224.0.0.16");
ACE_INET_Addr		localAddr;
ACE_SOCK_Dgram		scok(localAddr);
char buf[128];
while(1)
{
memset(buf,0,sizeof(buf));
std::cin.getline(buf,sizeof(buf));
if(0 == strcmp("quit",buf))
{
break;
}
if(scok.send(buf,sizeof(buf),mcastAddr) == -1)
{
ACE_ERROR_RETURN((LM_ERROR,"%p \n","send"),1);
}
}
return 0;
}

chunli@linux:~/ACE$ g++ udp_mulitcast_send.cpp -l ACE -Wall -o send && ./send
Hello ACE
中文测试
quit
chunli@linux:~/ACE$


UDP 多播 接收端程序:
chunli@linux:~/ACE$ cat udp_mulitcast_recv.cpp
/*****************************************************************
功能:ACE UDP 多播 接收端
描述:使用ACE网络库,实现简单的UDP 多播功能
作者:魂斗罗
日期:2016.10.29
邮箱:li_chunli@mail.com
版本:1.0
******************************************************************/
#include <iostream>
#include <ace/SOCK_Dgram_Mcast.h>
#include <ace/Log_Msg.h>
int main(int argc,char ** argv)
{
ACE_INET_Addr           mcastAddr(9988,"224.0.0.16");
ACE_INET_Addr           remoteAddr;
ACE_SOCK_Dgram_Mcast    sock;
if(sock.join(mcastAddr) == -1)
{
ACE_ERROR_RETURN((LM_ERROR,"%p \n","join"),1);
}
char buf[BUFSIZ];
while(1)
{
memset(buf,0,sizeof(buf));
if(sock.recv(buf,sizeof(buf),remoteAddr) != -1)
{
ACE_DEBUG((LM_DEBUG,"recv msg from %s: %d: %s\n",remoteAddr.get_host_addr(),remoteAddr.get_port_number(),buf));
}
//if(sock.leave(mcastAddr) == -1)
{
//	ACE_ERROR_RETURN((LM_ERROR,"%p \n","leave"),1);
}
}
return 0;
}
chunli@linux:~/ACE$

多开几个接收端:
窗口1
chunli@linux:~/ACE$ g++ udp_mulitcast_recv.cpp -l ACE -Wall  -o recv && ./recv
recv msg from 11.11.11.6: 45245: Hello ACE
recv msg from 11.11.11.6: 45245: 中文测试
窗口2
chunli@linux:~/ACE$ g++ udp_mulitcast_recv.cpp -l ACE -Wall  -o recv && ./recv
recv msg from 11.11.11.6: 45245: Hello ACE
recv msg from 11.11.11.6: 45245: 中文测试
窗口3
chunli@linux:~/ACE$ g++ udp_mulitcast_recv.cpp -l ACE -Wall  -o recv && ./recv
recv msg from 11.11.11.6: 45245: Hello ACE
recv msg from 11.11.11.6: 45245: 中文测试


UDP 广播测试
UDP 广播发送端 ip:11.11.11.6
chunli@linux:~/ACE$ cat broadcast_send.cpp
#include <iostream>
#include <ace/SOCK_Dgram_Bcast.h>
#include <ace/Log_Msg.h>
int main(void)
{
ACE_SOCK_Dgram_Bcast		sock(ACE_Addr::sap_any);
u_short				port = 8080;
char buf[BUFSIZ];
while(1)
{
memset(buf,0,sizeof(buf));
std::cin.getline(buf,sizeof(buf));
if(0 == strcmp("quit",buf))
break;
if(sock.send(buf,strlen(buf),port) == -1)
{
ACE_ERROR_RETURN((LM_ERROR,"%p \n","send"),1);
}
}
return 0;
}
chunli@linux:~/ACE$ g++ broadcast_send.cpp -l ACE -Wall -o send && ./send
Hello ACE
测试啊测试..........
quit
chunli@linux:~/ACE$


UDP 广播接收端 ip:11.11.11.17
chunli@ubuntu14:~$ cat broadcast_recv.cpp
#include <ace/SOCK_Dgram_Bcast.h>
#include <ace/Log_Msg.h>
int main(void)
{
ACE_INET_Addr		localAddr(8080);
ACE_INET_Addr		remoteAddr;
ACE_SOCK_Dgram_Bcast	sock(localAddr);
char buf[512];
while(1)
{
memset(buf,0,sizeof(buf));
if(sock.recv(buf,sizeof(buf),remoteAddr) != -1)
{
ACE_DEBUG((LM_DEBUG,"recv msg from %s:%d %s\n",remoteAddr.get_host_addr(),remoteAddr.get_port_number(),buf));
}
}
return 0;
}

chunli@ubuntu14:~$ g++ broadcast_recv.cpp  -l ACE -Wall -o bcast_recv && ./bcast_recv
recv msg from 11.11.11.6:50904 Hello ACE
recv msg from 11.11.11.6:50904 测试啊测试..........
^C
chunli@ubuntu14:~$
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  对象 跨平台 面向
相关文章推荐