我正在处理一个类似聊天室的项目,并且所有客户端都应该连接到服务器。但我使用TCP和我不想使用多播,我想服务器发送消息给某些specefic客户端。
我为一个客户编写了我的代码,但它运行良好,但我不知道如何为更多的客户提供它。
在我的编码中我使用了如下代码:
ipAdd = ipHostInfo.AddressList[0];
我知道数组0是服务器和我自己的机器。
是数组2 3和...其他连接到服务器的连接按顺序连接或....?
也许你说它是一个重复的问题,但我在网上找不到好的答案。 这是我为我的服务器试过的代码,并且只适用于一个客户端。 非常感谢。
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);
}
}
}
答案 0 :(得分:1)
一些建议,
如果您考虑现有场景,当我们聊天时,我们会明确知道我们与谁聊天。因此,如果您希望您的应用程序进行一对一通信,请执行映射"用户名"线程ID处理服务器中的每个客户端。然后为每个消息发送带有特定"用户名"所以在服务器上你可以识别转发该消息的线程。
记住您可以动态创建线程来处理更多客户端,并且还可以检查"在线客户端" [这可能是未来的实施]
相关信息:
Getting the thread ID from a thread [主管ID]
http://www.dotnetperls.com/hashtable [存储它们的东西]
P.S-首先尝试使用线程为每个新连接的客户端处理多个客户端。用户数组存储线程ID和东西,并使用while循环监听每个客户端。您可能需要锁定以避免竞争条件。