如何在服务器上指定客户端
本文关键字:客户端 服务器 | 更新日期: 2023-09-27 18:33:27
im 正在处理一个类似于聊天室的项目,所有客户端都应该连接到服务器。 但是我使用 TCP,我不想使用多播,我想服务器向某个特定的客户端发送消息。
我为一个客户端编写了代码,它运行良好,但我不知道如何为更多客户编写代码。
在我的编码中,我使用了如下代码:
ipAdd = ipHostInfo.AddressList[0];
我知道数组编号 0 是服务器和我自己的机器。
是阵列编号 2 3 和...其他按顺序连接到服务器的 Clint 还是....?
也许你说这是一个重复的问题,但我真的在互联网上找不到好的答案。这是我为我的服务器尝试的代码,并且只适用于一个客户端。多谢。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace Server_Environment
{
public partial class server_form : Form
{
public server_form()
{
InitializeComponent();
}
Socket listner;
Socket handler;
IPHostEntry ipHostInfo;
IPAddress ipAdd;
IPEndPoint localEndPoint;
const int maxClient = 10;
Thread thr1;
Thread thr2;
string data;
byte[] msg;
private delegate void setDisplay(string Text);
private delegate void EnableTrue(bool b);
private void Connection()
{
try
{
lblInitText("Waiting...");
ipHostInfo = Dns.Resolve(Dns.GetHostName());
ipAdd = ipHostInfo.AddressList[0];
localEndPoint = new IPEndPoint(ipAdd, 1369);
listner.Bind(localEndPoint);
listner.Listen(maxClient);
thr1 = new Thread(new ThreadStart(AcceptInit));
thr1.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void AcceptInit()
{
try
{
handler = listner.Accept();
thr2 = new Thread(new ThreadStart(DataReceiving));
thr2.Start();
lblInitText("connected");
EnableAfterConnect(true);
System.Media.SystemSounds.Exclamation.Play();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void DataReceiving()
{
try
{
byte[] bytes = new byte[1000];
int byteRec;
while (true)
{
while (true)
{
byteRec = handler.Receive(bytes);
if (byteRec > 0)
{
data = System.Text.Encoding.UTF8.GetString(bytes, 0, byteRec);
break;
}
}
LastMessage(data);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void LastMessage(string str)
{
try
{
if (lstchat.InvokeRequired == true)
{
setDisplay d = new setDisplay(lastmessage);
this.Invoke(d, new object[] { str });
}
else
{
lstchat.Items.Add("Client: " + str);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void lblInitText(string lblText)
{
if (lblstatus.InvokeRequired == true)
{
setDisplay dp = new setDisplay(lblInitText);
this.Invoke(dp, new object[] { lblText });
}
else
{
lblstatus.Text = lblText;
}
}
private void EnableAfterConnect(bool b)
{
if (txtmessage.InvokeRequired == true)
{
EnableTrue et = new EnableTrue(EnableAfterConnect);
this.Invoke(et, new object[] { b });
}
else
{
txtmessage.Enabled = b;
}
//----------
if (btnsend.InvokeRequired == true)
{
EnableTrue et = new EnableTrue(EnableAfterConnect);
this.Invoke(et, new object[] { b });
}
else
{
btnsend.Enabled = b;
}
//----------
if (lstchat.InvokeRequired == true)
{
EnableTrue et = new EnableTrue(EnableAfterConnect);
this.Invoke(et, new object[] { b });
}
else
{
lstchat.Enabled = b;
}
}
private void lastmessage(string str)
{
try
{
if (lstchat.InvokeRequired == true)
{
setDisplay dp = new setDisplay(lastmessage);
this.Invoke(dp, new object[] { str });
}
else
{
lstchat.Items.Add("Client: " + str);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void server_form_Load(object sender, EventArgs e)
{
IPHostEntry myHostInfo = Dns.Resolve(Dns.GetHostName());
listner = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
lstchat.Enabled = false;
txtmessage.Enabled = false;
btnsend.Enabled = false;
Connection();
}
private void server_form_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
try
{
handler.Shutdown(SocketShutdown.Both);
listner.Shutdown(SocketShutdown.Both);
thr1.Abort();
thr2.Abort();
}
catch
{
}
Environment.Exit(0);
}
private void btnsend_Click(object sender, EventArgs e)
{
try
{
if (txtmessage.Text != "")
{
msg = System.Text.Encoding.UTF8.GetBytes(txtmessage.Text);
handler.Send(msg);
lstchat.Items.Add("My: " + txtmessage.Text);
txtmessage.Text = "";
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void txtmessage_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13)
btnsend_Click(null,null);
}
}
}
一些建议,
如果您考虑现有场景,当我们聊天时,我们特别知道我们与谁聊天。因此,如果您希望您的应用程序具有一对一的通信,请执行诸如将"用户名"映射到处理服务器中每个客户端的线程 ID 之类的操作。然后,对于每条消息,使用特定的"用户名"发送消息,以便在服务器上确定要转发该消息的线程。
请记住,您可以动态创建线程来处理更多客户端,还可以检查"在线客户端"[这可能是未来的实现]
相关信息 :
从线程获取线程 ID [线程 ID]
http://www.dotnetperls.com/hashtable [存储它们的东西]
P.S-首先尝试为每个新连接的客户端使用线程处理多个具有多播的客户端。用户数组,用于存储线程 ID 和内容,并使用 while 循环侦听每个客户端。此处可能需要锁以避免争用条件。
http://www.dotnetperls.com/lock [了解锁]