[英]Receive multiple different messages TcpListener C#
大家好,我一直在尝试学习如何使用TcpListener和套接字在客户端服务器之间发送一些简单的文本消息。 我已经阅读了许多线程,这些线程似乎在显示如何读取_Buffer,让我们说一个循环以确保读取整个消息。 但是,我似乎无法弄清楚在收到第一个消息后如何获取第二个消息。 我可以很好地连接到服务器,并且可以得到第一条消息。 但是,如果我再次点击客户端上的发送按钮,则不会有任何消息发送到服务器。 这是我的代码:
// SERVER APPLICATION: -----------------------------------------------namespace TCP_Server { public partial class Form1 : Form { public Form1() { InitializeComponent(); }
private void btnStartServer_Click(object sender, EventArgs e) { // Define the TCP Listner: TcpListener _listner = new TcpListener(IPAddress.Parse("127.0.0.1"), 7777); // Start The Listner: _listner.Start(); //Show the server is now listening: listStatus.Items.Add("Server started - Listening on port 7777"); //Create a socket to accept - This is a Blocking Call: Socket _sock = _listner.AcceptSocket(); //When Client Connects show server has accepted the socket: listStatus.Items.Add("User from IP " + _sock.RemoteEndPoint); while (_sock.Connected) { // Create Byte to Receive Data: byte[] _Buffer = new byte[1024]; // Create integer to hold how large the Data Received is: int _DataReceived = _sock.Receive(_Buffer); // Lets Server Know Message is Received: listStatus.Items.Add("Message Received..."); // Convert Buffer to a String: string _Message = Encoding.ASCII.GetString(_Buffer); // Post Message to the Server Window: listStatus.Items.Add(_Message); _sock.Close(); } } }
}
// CLIENT APPLICATION: ----------------------------------------------------
namespace TCP__Client { public partial class Form1 : Form { public Form1() { InitializeComponent(); }
// Defind the TCP Client: TcpClient _Client = new TcpClient(); private void btnConnect_Click(object sender, EventArgs e) { // Connect the TCP Client: _Client.Connect("127.0.0.1", 7777); // Show the Client has Connected: listStatus.Items.Add("Connected to Server 127.0.0.1"); } private void btnSend_Click(object sender, EventArgs e) { while (_Client.Connected) { // Create a Stream: Stream _Stream = _Client.GetStream(); // Create Instance of an Encoder: ASCIIEncoding _Asc = new ASCIIEncoding(); byte[] _Buffer = new byte[1024]; // Create Buffer to Send Message: _Buffer = _Asc.GetBytes(txtMessage.Text); // Show Client is Sending Message: listStatus.Items.Add("Tranmitting Message..."); // Write Message to the Stream: _Stream.Write(_Buffer, 0, _Buffer.Length); // Close Stream _Stream.Close(); _Stream.Dispose(); } } }
}
如果有人可以解释如何做到这一点,我将不胜感激,我将不胜感激。 我在使用任务和线程方面确实有一点经验,这是我需要做的事情吗? 我只是想对此有所了解,所以我可以开始学习它。 如果有人有任何建议或示例对您有帮助,请分享。
当客户端仍连接到服务器时,请不要故意关闭服务器应用程序上的套接字。 由于您必须保持活动状态才能接收其他消息,因此请重复接收函数调用。 如果没有从客户端发送的数据,则Receive()函数调用将自动阻止当前线程等待可用数据。 如果再次单击客户端应用程序上的“发送消息”,则数据将可用于服务器,并将取消阻止服务器应用程序上的该阻止部分。
您的服务器应用程序可能会在AcceptSocket()和Receive()部分上阻止UI线程。 单击StartServer按钮时,由于没有可用的传入连接,您的服务器窗口(UI)可能没有响应,并且您在listStatus控件上看不到消息。 因此,最好将这些Socket代码片段放在单独的线程上运行,以免阻塞UI线程。 要从单独的线程处理UI组件,需要执行线程安全的UI操作。
这是我所做的更改:
服务器
namespace Tcp_Server
{
public partial class Form1 : Form
{
delegate void AddTextCallback(string text);
public Form1()
{
InitializeComponent();
}
private void btnStartServer_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ServerHandler));
}
private void ServerHandler(object args)
{
TcpListener _listner = new TcpListener(IPAddress.Parse("127.0.0.1"), 7777);
// Start The Listner:
_listner.Start();
//Show the server is now listening (Note: UI Thread-Safe is required):
AddText("Server started - Listening on port 7777");
//Create a socket to accept - This is a Blocking Call:
Socket _sock = _listner.AcceptSocket();
//When Client Connects show server has accepted the socket:
AddText("User from IP " + _sock.RemoteEndPoint);
while (_sock.Connected)
{
// Create Byte to Receive Data:
byte[] _Buffer = new byte[1024];
// Create integer to hold how large the Data Received is:
int _DataReceived = _sock.Receive(_Buffer);
if (_DataReceived == 0)
{
// Socket has been shutdown by the client.
break;
}
// Lets Server Know Message is Received:
AddText("Message Received...");
// Convert Buffer to a String:
string _Message = Encoding.ASCII.GetString(_Buffer);
// Post Message to the Server Window:
AddText(_Message);
}
_sock.Close();
//When Client disconnect from the server:
AddText("Client Disconnected.");
_listner.Stop();
AddText("Server Stop.");
}
private void AddText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.listStatus.InvokeRequired)
{
AddTextCallback d = new AddTextCallback(AddText);
this.Invoke(d, new object[] { text });
}
else
{
this.listStatus.Items.Add(text);
}
}
}
}
客户
namespace Tcp_Client
{
public partial class Form1 : Form
{
// Defind the TCP Client:
TcpClient _Client = null;
Stream _Stream = null;
public Form1()
{
InitializeComponent();
}
private void btnConnect_Click(object sender, EventArgs e)
{
_Client = new TcpClient();
// Connect the TCP Client:
_Client.Connect("127.0.0.1", 7777);
// Show the Client has Connected:
listStatus.Items.Add("Connected to Server 127.0.0.1");
// Create a Stream:
_Stream = _Client.GetStream();
}
private void btnSend_Click(object sender, EventArgs e)
{
if (_Client.Connected)
{
// Create Instance of an Encoder:
ASCIIEncoding _Asc = new ASCIIEncoding();
byte[] _Buffer = new byte[1024];
// Create Buffer to Send Message:
_Buffer = _Asc.GetBytes(txtMessage.Text);
// Show Client is Sending Message:
listStatus.Items.Add("Tranmitting Message...");
// Write Message to the Stream:
_Stream.Write(_Buffer, 0, _Buffer.Length);
}
}
private void btnDisconnect_Click(object sender, EventArgs e)
{
_Stream.Close();
_Stream.Dispose();
_Client.Close();
listStatus.Items.Add("Disconnected from server.");
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.