C#使用Socket实现局域网聊天攻略
简介
本攻略将介绍如何使用C#中的Socket类实现基于局域网的聊天功能。在该聊天室中,客户端和服务器端都需要使用Socket类来完成通信功能。在进入具体实现前,需要先说明一些基础概念和准备工作。
基础概念
-
Socket:Socket是实现网络通信的底层操作。它是位于传输层的,用于实现网络应用程序之间的双向通信。
-
IP地址:计算机在网络中的位置。IP地址由32位二进制数组成,通常用点分十进制表示。
-
端口:是网络通信时用来识别服务的数字,通常是16位的整数。端口有两个范围:从0到1023的端口是系统用的,应用程序一般不能使用;从1024到65535的端口是留给应用程序使用。
准备工作
在开始实现聊天功能前,需要先准备好Visual Studio开发环境,选择合适的.NET框架(推荐使用.NET Framework 4.0及以上)以及安装Common.Logging库,方便后面的日志输出。
实现
服务端
在服务端,我们需要做如下操作:
- 创建一个Socket对象,指定地址族(AF_INET)和套接字类型(SOCK_STREAM),并绑定到本地IP地址和端口号上。
private static void StartServer()
{
try
{
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 1234);
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(10);
Console.WriteLine("Waiting for client...");
while (true)
{
Socket handler = listener.Accept();
ReceiveMessage(handler);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
-
监听端口,接受客户端连接请求。
-
收到客户端发送的消息后,解析消息并进行回复。
private static void ReceiveMessage(Socket handler)
{
byte[] bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
string data = Encoding.ASCII.GetString(bytes, 0, bytesRec);
Console.WriteLine("Received message: {0}", data);
byte[] msg = Encoding.ASCII.GetBytes("Server received message");
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
以上为服务端的主要代码实现。其中,ReceiveMessage会解析客户端发送的消息并进行回复。
客户端
在客户端,我们需要做如下操作:
- 创建一个Socket对象,指定地址族(AF_INET)和套接字类型(SOCK_STREAM),并连接到服务端的IP地址和端口号上。
private static void StartClient()
{
try
{
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 1234);
Socket sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
sender.Connect(remoteEP);
Console.WriteLine("Connected to server...");
SendMessage(sender);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
- 向服务端发送消息,并接收服务端的回复。
private static void SendMessage(Socket sender)
{
byte[] msg = Encoding.ASCII.GetBytes("Client sending message");
sender.Send(msg);
byte[] bytes = new byte[1024];
int bytesRec = sender.Receive(bytes);
string data = Encoding.ASCII.GetString(bytes, 0, bytesRec);
Console.WriteLine("Server reply: {0}", data);
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
以上为客户端的主要代码实现。SendMessage会向服务端发送消息,并接收服务端的回复。
示例1
在示例1中,我们将开启一个控制台程序作为服务端,然后开启一个或多个客户端。在控制台中输入消息,并在客户端之间进行消息的传递。示例代码如下:
服务端
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
StartServer();
}
private static void StartServer()
{
try
{
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 1234);
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(10);
Console.WriteLine("Waiting for client...");
while (true)
{
Socket handler = listener.Accept();
ReceiveMessage(handler);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private static void ReceiveMessage(Socket handler)
{
byte[] bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
string data = Encoding.ASCII.GetString(bytes, 0, bytesRec);
Console.WriteLine("Received message: {0}", data);
byte[] msg = Encoding.ASCII.GetBytes("Server received message");
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
}
客户端
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
StartClient();
}
private static void StartClient()
{
try
{
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 1234);
Socket sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
sender.Connect(remoteEP);
Console.WriteLine("Connected to server...");
SendMessage(sender);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private static void SendMessage(Socket sender)
{
byte[] msg = Encoding.ASCII.GetBytes("Client sending message");
sender.Send(msg);
byte[] bytes = new byte[1024];
int bytesRec = sender.Receive(bytes);
string data = Encoding.ASCII.GetString(bytes, 0, bytesRec);
Console.WriteLine("Server reply: {0}", data);
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
}
}
示例2
在示例2中,我们将基于Window Form应用程序实现聊天功能。代码如下:
服务端
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication
{
public partial class ServerForm : Form
{
private Thread listenerThread;
private Socket listener;
bool done = false;
public ServerForm()
{
InitializeComponent();
}
private void Btn_Start_Click(object sender, EventArgs e)
{
StartServer();
}
private void StartServer()
{
try
{
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 1234);
listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(10);
listenerThread = new Thread(ListenThread);
listenerThread.Start();
listBox1.Items.Add("Waiting for connection...");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ListenThread()
{
while (!done)
{
try
{
Socket handler = listener.Accept();
ReceiveMessage(handler);
}
catch { }
}
}
private void ReceiveMessage(Socket handler)
{
byte[] bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
string data = Encoding.ASCII.GetString(bytes, 0, bytesRec);
listBox1.Invoke((MethodInvoker)delegate {
listBox1.Items.Add(data);
});
byte[] msg = Encoding.ASCII.GetBytes("Message received on server: " + data);
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
private void ServerForm_FormClosing(object sender, FormClosingEventArgs e)
{
done = true;
listenerThread.Abort();
listener.Close();
}
}
}
客户端
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication
{
public partial class ClientForm : Form
{
private Socket client;
public ClientForm()
{
InitializeComponent();
}
private void Btn_Connect_Click(object sender, EventArgs e)
{
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(txt_IP.Text), 1234);
try
{
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(remoteEP);
MessageBox.Show("Connected to server...");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void Btn_Send_Click(object sender, EventArgs e)
{
if (client != null && client.Connected)
{
byte[] msg = Encoding.ASCII.GetBytes(txt_Message.Text);
client.Send(msg);
byte[] bytes = new byte[1024];
int bytesRec = client.Receive(bytes);
string data = Encoding.ASCII.GetString(bytes, 0, bytesRec);
MessageBox.Show(data);
}
else
{
MessageBox.Show("Not connected to server...");
}
txt_Message.Clear();
}
private void ClientForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (client != null && client.Connected)
{
client.Shutdown(SocketShutdown.Both);
client.Close();
}
}
}
}
以上为基于Windows Form应用程序的聊天应用程序实现示例。其中,服务端代码基本与控制台程序相同,只是添加了对界面控件的调用。客户端的实现相对简单,只需完成连接和发送消息的操作。
总结
本攻略介绍了如何使用C#中的Socket类实现基于局域网的聊天功能。通过示例程序的使用,可以加深对Socket通信的理解,并掌握相关编程技能。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#使用Socket实现局域网聊天 - Python技术站