E006

调用orsci-art中的UDP,实现UDP聊天演示。

 

// E006
//By Jiang Wei 演示UDP的聊天程序
//http://www.orsci.cn

#include "stdafx.h"
#include <iostream>
using namespace std;

#include "orsciART.h"
using namespace art;

int _tmain(int argc, _TCHAR* argv[])
{
//TUDPTools::Demo_UDPServer(); //E006演示程序编译服务器
TUDPTools::Demo_UDPClient(); //E006演示程序编译客户端

return 0;
}


inline void TUDPTools::Demo_UDPServer() //注:本代码已在art包中作为UDP演示程序实现。
{
cout << " ============ E006:UDP Server by jiangwei 2011-12-29=============" << endl;
cout << " http://www.orsci.cn" << endl;

TNetTools::Demo_DispLocalNetWorkInfo();

char buf[TUDP::ctMaxBufLen];
//-----------------------------------------
TUDP mUDP;
mUDP.EnableBroadcast(true);
cout << "准备打开UDP..." << endl;
cout << "请输入服务器地址(例如127.0.0.1)..." << endl;
string mIP;
while (mIP == "") cin >> mIP;
if (mIP.size() < 5) mIP = "127.0.0.1";
cout << "本机IP地址:" << mIP << endl;
unsigned short mPort;
cout << "请输入服务器的端口号(例如:2910):";
cin >> mPort;
//mUDP.Open("127.0.0.1", mPort);
mUDP.Open(mIP, mPort);
if (mUDP.is_open() == false)
{
cout << "Sorry,UDP服务启动失败,通常是不正确的IP地址或端口!" << endl;
return;
}
else cout << "端口绑定成功!真实的本地IP地址:" << mUDP.LocalIP() << " 本地端口:" << mUDP.LocalPort() << endl;

cout << "最大发送缓冲区大小:" << TUDPTools::getsocketopt_SO_SNDBUF((SOCKET)mUDP.udpsocket()) << endl;
cout << "最大接收缓冲区大小:" << TUDPTools::getsocketopt_SO_RCVBUF((SOCKET)mUDP.udpsocket()) << endl;
cout << "最大数据报大小:" << TUDPTools::GetSocketOptMaxMSGSize((SOCKET)mUDP.udpsocket()) << endl;
cout << "服务器打开情况:" << mUDP.is_open() << endl;
cout << TUDPTools::getsockopt_SO_BROADCAST((SOCKET)mUDP.udpsocket()) << endl;

//mUDP.SendBufferOK("127.0.0.1", 4612, buf, strlen(buf));

int mCounter = 0;
string mPeerIP;
unsigned short mPeerPort;
while (true)
{
//int mByteCount = mUDP.RecvBuffer(buf, sizeof(buf), mPeerIP, mPeerPort, 20000);
//int mByteCount = mUDP.SendBuffer("127.0.0.255", 4612, buf, strlen(buf), 20000);
int mByteCount = mUDP.RecvBuffer(buf, sizeof(buf), mPeerIP, mPeerPort, 30*1000);
if (mByteCount > 0)
{
cout << "信息来自:" << mPeerIP << ":" << mPeerPort << " 接收数量:" << mByteCount << endl;
buf[mByteCount] = 0; //设置字符串末尾
string mRecvMsg = buf;
cout << "接收消息:" << mRecvMsg << endl;

//回复消息
sprintf(buf, "%s-%d", "小鬼,看看天!", mCounter++);
mUDP.SendBuffer(mPeerIP, mPeerPort, buf, strlen(buf), 20000);
}
}

cout << "准备关闭UDP" << endl;
mUDP.Close();
cout << mUDP.is_open() << endl;
}


inline void TUDPTools::Demo_UDPClient()//注:本代码已在art包中作为UDP演示程序实现。
{
cout << " ============ E006:UDP Client by jiangwei 2011-12-29=============" << endl;
cout << " http://www.orsci.cn" << endl;

TNetTools::Demo_DispLocalNetWorkInfo();

char buf[TUDP::ctMaxBufLen];
//-----------------------------------------
TUDP mUDP;
mUDP.EnableBroadcast(true);

string mIP;
cout << "输入本机的IP地址(例如:127.0.0.1):";
while (mIP == "") cin >> mIP;
if (mIP.size() < 5) mIP = "127.0.0.1";

unsigned short mPort;
//mUDP.Open("127.0.0.1", 0);
mUDP.Open(mIP, 0); //0代表自动分配一个本地端口号!
if (mUDP.is_open() == false)
{
cout << "Sorry,UDP服务启动失败,通常是不正确的IP地址或端口!" << endl;
return;
}
else cout << "端口绑定成功!本地IP地址:" << mUDP.LocalIP() << " 本地端口:" << mUDP.LocalPort() << endl;
mPort = mUDP.LocalPort();
cout << TUDPTools::getsockopt_SO_BROADCAST((SOCKET)mUDP.udpsocket()) << endl;

string mPeerIP;
cout << "请输入服务器IP地址(例如127.0.0.1):";
while (mPeerIP == "") cin >> mPeerIP;
if (mPeerIP.size() < 5) mPeerIP = "127.0.0.1";

unsigned short mPeerPort;
cout << "请输入服务器的端口号(例如:2910):";
cin >> mPeerPort;

sprintf(buf, "%s", "小鬼,我来了!");
int mByteCount = mUDP.SendBuffer(mPeerIP, mPeerPort, buf, strlen(buf), 5000); //限5秒内发送成功。
cout << "发送数量:" << mByteCount << endl;

string mMsg;
while (true)
{
cout << "请输入要发送的消息(q--退出):";
while (mMsg == "") std::cin >> mMsg;
if (mMsg == "q") return;
sprintf(buf, "%s", mMsg.c_str());
mMsg = "";
int mByteCount = mUDP.SendBuffer(mPeerIP, mPeerPort, buf, strlen(buf), 5000); //限5秒内发送成功。
cout << "发送数量:" << mByteCount << endl;

mByteCount = mUDP.RecvBuffer(buf, sizeof(buf), mIP, mPort, 100); //0.05秒内接收消息
while (mByteCount > 0)
{
cout << "收到来自:" << mIP << ":" << mPort << "消息长度:" << mByteCount << endl;
buf[mByteCount] = 0;
cout << buf << endl;
mByteCount = mUDP.RecvBuffer(buf, sizeof(buf), mIP, mPort, 100); //0.05秒内接收消息
}
}

mUDP.Close();
}

 

输出

(一)服务器运行图

服务器运行图.

(二)客户端运行图

客户端运行图

说明:

(1)可以同时运行多个客户端,向服务器发送信息;也可以各个客户端之间发送信息。体现出UDP的面向非连接的网络应用程序特点。

(2)如果想获得更好的服务体验,需要进行多线程编程。orsci包支持多线程编程,提供TThread基础类。

书籍 姜维. 《分布式网络系统与Multi-Agent系统编程框架》
软件 orsci-art开发包(C++语言)。