C# 用Socket写一个点对点通信,要求客户端既是服务端又是服务端,界面上有连接按钮,断开按钮,发送按钮,两个RichTextBox控件,
时间: 2023-06-14 21:08:06 浏览: 104
以下是基于C#的Socket编写点对点通信的代码,客户端既是服务端又是服务端,具有连接、断开、发送等功能,界面上有连接按钮、断开按钮、发送按钮和两个RichTextBox控件:
```csharp
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace P2PCommunicate
{
public partial class Form1 : Form
{
private Socket _serverSocket; // 服务端Socket
private Socket _clientSocket; // 客户端Socket
private Thread _serverThread; // 服务端线程
private Thread _clientThread; // 客户端线程
private bool _isServerStarted; // 服务端是否已启动
private bool _isClientStarted; // 客户端是否已启动
private string _serverIp = "127.0.0.1"; // 服务端IP地址
private int _serverPort = 8888; // 服务端端口号
private string _clientIp = "127.0.0.1"; // 客户端IP地址
private int _clientPort = 8889; // 客户端端口号
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
UpdateUI(true);
}
private void btnConnect_Click(object sender, EventArgs e)
{
if (!_isClientStarted)
{
_clientThread = new Thread(ClientThreadFunc);
_clientThread.Start();
}
else
{
MessageBox.Show("客户端已经连接!", "提示");
}
}
private void btnDisconnect_Click(object sender, EventArgs e)
{
if (_isClientStarted)
{
_clientSocket.Close();
_clientThread.Abort();
_isClientStarted = false;
UpdateUI(false);
}
else
{
MessageBox.Show("客户端未连接!", "提示");
}
}
private void btnSend_Click(object sender, EventArgs e)
{
if (_isClientStarted)
{
SendMessage(txtSend.Text);
txtSend.Clear();
}
else
{
MessageBox.Show("客户端未连接!", "提示");
}
}
private void ServerThreadFunc()
{
try
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_serverSocket.Bind(new IPEndPoint(IPAddress.Parse(_serverIp), _serverPort));
_serverSocket.Listen(10);
while (true)
{
Socket client = _serverSocket.Accept();
Thread receiveThread = new Thread(ReceiveThreadFunc);
receiveThread.Start(client);
}
}
catch (Exception ex)
{
MessageBox.Show("服务端异常:" + ex.Message, "错误");
}
}
private void ClientThreadFunc()
{
try
{
_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_clientSocket.Connect(new IPEndPoint(IPAddress.Parse(_clientIp), _clientPort));
Thread receiveThread = new Thread(ReceiveThreadFunc);
receiveThread.Start(_clientSocket);
_isClientStarted = true;
UpdateUI(true);
}
catch (Exception ex)
{
MessageBox.Show("客户端异常:" + ex.Message, "错误");
}
}
private void ReceiveThreadFunc(object obj)
{
Socket socket = obj as Socket;
byte[] buffer = new byte[1024];
while (true)
{
int length = socket.Receive(buffer);
string message = Encoding.UTF8.GetString(buffer, 0, length);
AppendText(txtReceive, string.Format("[{0:HH:mm:ss}] {1}", DateTime.Now, message));
}
}
private void SendMessage(string message)
{
byte[] buffer = Encoding.UTF8.GetBytes(message);
_clientSocket.Send(buffer);
AppendText(txtReceive, string.Format("[{0:HH:mm:ss}] {1}", DateTime.Now, message));
}
private void AppendText(RichTextBox box, string text)
{
if (box.InvokeRequired)
{
box.Invoke(new Action<RichTextBox, string>(AppendText), box, text);
}
else
{
box.AppendText(text + Environment.NewLine);
}
}
private void UpdateUI(bool isConnected)
{
btnConnect.Enabled = !isConnected;
btnDisconnect.Enabled = isConnected;
btnSend.Enabled = isConnected;
txtSend.Enabled = isConnected;
txtReceive.Enabled = isConnected;
}
}
}
```
在窗体设计中,需要添加一个连接按钮(btnConnect)、一个断开按钮(btnDisconnect)、一个发送按钮(btnSend)、一个发送文本框(txtSend)、一个接收文本框(txtReceive)和两个标签(lblServer、lblClient)。
注意:该程序中客户端和服务端使用的是不同的端口号,可以根据实际需要进行修改。
阅读全文