-
ACE Tutorial [翻译] 08-page03
2004-11-29
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://jnn.blogbus.com/logs/520210.html
在 directed_client.cpp我们创建一个客户端来向指定的服务器发送数据报。如果你知道服务器在什么地方,这是一个比较好的建立连接的方法。例如在Unix中的talk服务,就是采用这样的方式来实现的。
// page03.html,v 1.13 2000/11/27 17:56:43 othman Exp#include "ace/Log_Msg.h"
#include "ace/SOCK_Dgram.h"
#include "ace/INET_Addr.h"
/* Once again, we use the default server port. In a "real" system,
the server's port (or ports) would be published in some way so thatclients would know where to "look". We could even add entries to
the operating system's services file and use a service name insteadof a number. We'll come back to that in some other tutorialthough. For now, let's stay simple.这里,我们还是选定缺省的服务器端口好。在实际系统中,服务器的端口号(端口号组)可以通过某种方式来发布,这样客户端就知道如何来查找服务器。我们也可以通过向操作系统的服务文件添加项目,通过项目来取代相应的数字。如果感兴趣的化,可以通过其他的教程来学习相关的内容。*/static const u_short PORT = ACE_DEFAULT_SERVER_PORT;/* Our goal here is to develop a client that can send a datagram to aserver running on a known host. We'll use a command-line argumentto specify the hostname instead of hard-coding it.我们目前要实现的功能就是要开发一个客户端,能够向指定的服务器发送数据报。我们使用命令行参数来指定相关的主机,而不是写进我们到我们的代码里。*/intmain (int argc,char *argv[]){/* All datagrams must have a point of origin. Since we intend to
transmit instead of receive, we initialize an address with zeroand let the OS choose a port for us. We could have chosen our ownvalue between 1025 and 65535 as long as it isn't already in use.所有的数据报都需要有一个源点。由于我们是发送数据而不是接收数据,我们将地址初始化伟0,并且让OS来为我们选择一个端口。我们也可以选择1025到65535之间的没有被使用的任意端口。The biggest difference between client and server when datagramsare used is the fact that servers tend to have a known/fixedaddress at which they listen and clients tend to have arbitraryaddresses assigned by the OS.客户端与服务器端的最大的不同是服务器端的数据报是监听一个众所周知/固定的地址,而客户端倾向于使用OS分配的地址。*/ACE_INET_Addr local((u_short) 0);/* And here is our datagram object.
这是我们的数据报对象*/ACE_SOCK_Dgram dgram;/* Notice that this looks a lot like the server application.
There's no difference in creating server datagrams an clientdatagrams. You can even use a zero-constructed address for yourserver datagram as long as you tell the client where you'relistening (eg -- by writting into a file or some such).注意这和服务器端的应用有很多相同的地方。在客户端创建数据报是和服务器端创建数据报没有什么不同。只要你能告诉客户端你监听的端口(例如把端口号写到文件里面),你就可以向服务器端的数据包传入一个空值的地址。*/if (dgram.open (local) == -1)ACE_ERROR_RETURN ((LM_ERROR,"%p\n",
"datagram open"),
-1);/* Yep. We've seen this before too...
这和我们以前看到的一样*/char buf[BUFSIZ];/* Ok, now we're doing something different.
现在我们做一些不同的事情*/sprintf (buf, "Hello World!");
/* Just like sending a telegram, we have to address our datagram.
Here, we create an address object at the desired port on thechosen host. To keep us from crashing, we'll provide a defaulthost name if we aren't given one.和发送电报一样,我们也需要指定我们的发送地址。这里我们为我们选定的主机指定的端口创建一个地址对象。为了防止程序崩溃,如果没有选定主机地址我们需要提供一个缺省的主机,*/ACE_INET_Addr remote (PORT,argc > 1 ? argv[1] : "localhost");
ACE_DEBUG ((LM_DEBUG,"(%P|%t) Sending (%s) to the server.\n",
buf));/* Now we send our buffer of stuff to the remote address. This is
just exactly what the server did after receiving a client message.Datagrams are rather orthogonal that way: they don't generallymake much of a fuss about being either client or server.现在我们把buffer的数据发送到远端的地址去。这和服务器接收到客户端的发送的数据一样的处理方法,对于数据报来说,服务器和客户端基本没有区别。*/if (dgram.send (buf,ACE_OS::strlen (buf) + 1,
remote) == -1)ACE_ERROR_RETURN ((LM_ERROR,"%p\n",
"send"),
-1);/* Now we've turned around and put ourselves into "server mode" by
invoking the recv() method. We know our server is going to sendus something, so we hang out here and wait for it. Because weknow datagrams are unreliable, there is a chance that the serverwill respond but we won't hear. You might consider providing atimeout on the recv() in that case. If recv() fails due totimeout it will return -1 and you can then resend your query andattempt the recv() again.现在通过调用recv()方法,我们需要转变角色到“服务模式”。我们知道服务器会给我们发送消息,所有我们阻塞在这里,等待服务器发送的消息。因为我们知道数据报是不可靠的,服务器发送过来的消息,我们有可能会接收不到。你也许会考虑让recv()提供一个一个超时参数。 如果recv()由于超时返回失败,他将会返回一个-1,你可以可以重新发送一个你的请求,再尝试接收一次。Like the server application, we have to give the recv() anuninitialized addr object so that we can find out who is talkingback to us.和服务应用一样,我们需要给recv()指定一个没有初始化的地址对象,这样我们就可以知道谁回应我们的消息了。*/if (dgram.recv (buf,sizeof (buf),remote) == -1)ACE_ERROR_RETURN ((LM_ERROR,"%p\n",
"recv"),
-1);/* Find out what the server had to say.
显示服务器返回的消息*/ACE_DEBUG ((LM_DEBUG,"(%P|%t) The server said: %s\n",
buf));/* Using the "remote" object instance, find out where the server
lives. We could then save this address and use directed datagramsto chat with the server for a while.使用remote 对象实例,显示服务器的地址。 接下来我们可以将这个地址保存,然后通过数据报直接和服务器进行对话。*/ACE_DEBUG ((LM_DEBUG,"(%P|%t) The server can be found at: (%s:%d)\n",
remote.get_host_name(),PORT));return 0;}
这就这么简单明了,但是现阶段我们所做只是和我们知道的服务器进行对话,但是没能发现我们未知的服务器。现在你可以之间发送数据报到你网络中任何主机,但是这不是最佳的解决方案。再下一页,我们将向你展示正确的做法。
历史上的今天:
ACE Tutorial [翻译] 08-page04 2004-11-29ACE Tutorial [翻译] 08-page02 2004-11-29ACE Tutorial [翻译] 08-page01 2004-11-29随机文章:
ACE Tutorial [翻译] 08-page04 2004-11-29ACE Tutorial [翻译] 08-page02 2004-11-29ACE Tutorial [翻译] 08-page01 2004-11-29ACE Tutorial [翻译] 06 -page05 2004-11-21ACE Tutorial [翻译] 06 -page04 2004-11-21
收藏到:Del.icio.us







