使用 UDPClient 生成聊天客户端
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
public class Chat {
private static UdpClient m_Client;
private static int ListenerPort = 8080;
private static int SenderPort = 8080;
private static int LocalPort;
private static int RemotePort;
private static string m_szHostName;
private static IPAddress m_GroupAddress;
private static IPHostEntry m_LocalHost;
private static IPEndPoint m_RemoteEP;
private static bool m_Done = false;
public static void Usage() {
Console.WriteLine("UDP 多路广播聊天实用工具");
Console.WriteLine("\n用法::");
Console.WriteLine("chat.exe");
}
public static void Main( String [] args ) {
LocalPort = SenderPort;
RemotePort = ListenerPort;
if( args.Length > 0 ) {
//
// 输出帮助消息,因为此实用工具不采用任何参数
//
Usage();
return;
}
m_szHostName = Dns.GetHostName();
m_LocalHost = Dns.GetHostByName(m_szHostName);
Console.WriteLine("本地端口:{0},远程端口:{1}", LocalPort, RemotePort);
Console.WriteLine("正在初始化");
Initialize();
Console.WriteLine("正在启动侦听器线程");
Thread t = new Thread(new ThreadStart(Listener));
t.Start();
Byte [] buffer = null;
Encoding ASCII = Encoding.ASCII;
bool m_ShuttingDown = false;
while(!m_ShuttingDown) {
String s = Console.ReadLine();
if( s.Length == 0 )
continue;
if(String.Compare(s,0,"@",0,1) == 0) {
m_Done = true;
//
// 将结束符发送给我们自己,
// 以便接收线程可以关闭
//
s = m_szHostName + ":@";
m_ShuttingDown = true;
} else {
s = m_szHostName + ":" + s;
}
buffer = new Byte[s.Length + 1];
//
// 将数据发送给远程对方主机
//
int len = ASCII.GetBytes( s.ToCharArray(), 0, s.Length, buffer, 0);
int ecode = m_Client.Send(buffer, len, m_RemoteEP);
if(ecode <= 0) {
Console.WriteLine("发送时出错:" + ecode);
}
}
t.Abort();
t.Join();
Console.WriteLine("正在关闭连接");
Terminate();
} // Main
public static void Terminate() {
m_Client.DropMulticastGroup(m_GroupAddress);
}
public static void Initialize() {
//
// 实例化 UdpCLient
//
m_Client = new UdpClient(LocalPort);
//
// 创建多路广播组对象
//
m_GroupAddress = IPAddress.Parse("224.0.0.1");
//
// 联接组
//
try {
m_Client.JoinMulticastGroup(m_GroupAddress, 100);
} catch(Exception) {
Console.WriteLine("无法联接多路广播组");
}
//
// 创建对方主机的终结点
//
m_RemoteEP = new IPEndPoint( m_GroupAddress, RemotePort );
}
public static void Listener() {
//
// 侦听器等待数据到来
// 并用缓冲区保存它。
Thread.Sleep(2000); // 确保 client2 正在接收
Encoding ASCII = Encoding.ASCII;
while(!m_Done) {
IPEndPoint endpoint = null;
Byte[] data = m_Client.Receive(ref endpoint);
String strData = ASCII.GetString(data);
if( strData.IndexOf(":@") > 0 ) {
//
// 我们接收到一个终止指示,
// 现在我们必须确定它是来
// 自我们的主线程的关闭,
// 还是来自其他地方
//
Char [] separators = {':'};
String [] vars = strData.Split(separators);
if( vars[0] == m_szHostName ) {
//
// 这是来自我们自己的线程,因此
// 立即结束
//
Console.WriteLine("正在关闭侦听器线程");
//
// 此过程应已由主线程完成了,但为
// 安全起见,我们再执行一次
//
m_Done = true;
}
else {
//
// 这是来自其他地方的
//
Console.WriteLine("{0} 已离开对话", vars[0]);
}
}
else {
//
// 这是从其他地方以及我们自己
// 处接收到的正常数据
// 在输出前,查看它是否来自我
// 们自己
//
if(strData.IndexOf(":") > 0) {
Char [] separators = {':'};
String [] vars = strData.Split(separators);
if( vars[0] != m_szHostName ) {
Console.WriteLine(strData);
}
}
}
}
Console.WriteLine("侦听器线程已完成");
return;
}
}
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
public class Chat {
private static UdpClient m_Client;
private static int ListenerPort = 8080;
private static int SenderPort = 8080;
private static int LocalPort;
private static int RemotePort;
private static string m_szHostName;
private static IPAddress m_GroupAddress;
private static IPHostEntry m_LocalHost;
private static IPEndPoint m_RemoteEP;
private static bool m_Done = false;
public static void Usage() {
Console.WriteLine("UDP 多路广播聊天实用工具");
Console.WriteLine("\n用法::");
Console.WriteLine("chat.exe");
}
public static void Main( String [] args ) {
LocalPort = SenderPort;
RemotePort = ListenerPort;
if( args.Length > 0 ) {
//
// 输出帮助消息,因为此实用工具不采用任何参数
//
Usage();
return;
}
m_szHostName = Dns.GetHostName();
m_LocalHost = Dns.GetHostByName(m_szHostName);
Console.WriteLine("本地端口:{0},远程端口:{1}", LocalPort, RemotePort);
Console.WriteLine("正在初始化");
Initialize();
Console.WriteLine("正在启动侦听器线程");
Thread t = new Thread(new ThreadStart(Listener));
t.Start();
Byte [] buffer = null;
Encoding ASCII = Encoding.ASCII;
bool m_ShuttingDown = false;
while(!m_ShuttingDown) {
String s = Console.ReadLine();
if( s.Length == 0 )
continue;
if(String.Compare(s,0,"@",0,1) == 0) {
m_Done = true;
//
// 将结束符发送给我们自己,
// 以便接收线程可以关闭
//
s = m_szHostName + ":@";
m_ShuttingDown = true;
} else {
s = m_szHostName + ":" + s;
}
buffer = new Byte[s.Length + 1];
//
// 将数据发送给远程对方主机
//
int len = ASCII.GetBytes( s.ToCharArray(), 0, s.Length, buffer, 0);
int ecode = m_Client.Send(buffer, len, m_RemoteEP);
if(ecode <= 0) {
Console.WriteLine("发送时出错:" + ecode);
}
}
t.Abort();
t.Join();
Console.WriteLine("正在关闭连接");
Terminate();
} // Main
public static void Terminate() {
m_Client.DropMulticastGroup(m_GroupAddress);
}
public static void Initialize() {
//
// 实例化 UdpCLient
//
m_Client = new UdpClient(LocalPort);
//
// 创建多路广播组对象
//
m_GroupAddress = IPAddress.Parse("224.0.0.1");
//
// 联接组
//
try {
m_Client.JoinMulticastGroup(m_GroupAddress, 100);
} catch(Exception) {
Console.WriteLine("无法联接多路广播组");
}
//
// 创建对方主机的终结点
//
m_RemoteEP = new IPEndPoint( m_GroupAddress, RemotePort );
}
public static void Listener() {
//
// 侦听器等待数据到来
// 并用缓冲区保存它。
Thread.Sleep(2000); // 确保 client2 正在接收
Encoding ASCII = Encoding.ASCII;
while(!m_Done) {
IPEndPoint endpoint = null;
Byte[] data = m_Client.Receive(ref endpoint);
String strData = ASCII.GetString(data);
if( strData.IndexOf(":@") > 0 ) {
//
// 我们接收到一个终止指示,
// 现在我们必须确定它是来
// 自我们的主线程的关闭,
// 还是来自其他地方
//
Char [] separators = {':'};
String [] vars = strData.Split(separators);
if( vars[0] == m_szHostName ) {
//
// 这是来自我们自己的线程,因此
// 立即结束
//
Console.WriteLine("正在关闭侦听器线程");
//
// 此过程应已由主线程完成了,但为
// 安全起见,我们再执行一次
//
m_Done = true;
}
else {
//
// 这是来自其他地方的
//
Console.WriteLine("{0} 已离开对话", vars[0]);
}
}
else {
//
// 这是从其他地方以及我们自己
// 处接收到的正常数据
// 在输出前,查看它是否来自我
// 们自己
//
if(strData.IndexOf(":") > 0) {
Char [] separators = {':'};
String [] vars = strData.Split(separators);
if( vars[0] != m_szHostName ) {
Console.WriteLine(strData);
}
}
}
}
Console.WriteLine("侦听器线程已完成");
return;
}
}
/************************************************/
本博客内容如果是原著都会在标题后加上(原著)字样,未加者多数为转载.
/************************************************/