我正在尝试调试它,但是我的脑海变得一团糟,在这方面我确实需要一点帮助。我正在使用具有多个客户端和一台服务器的经典的“聊天应用程序”。到目前为止,我有什么:
我的问题与第三步有关,在服务器端,我的程序正确输出了该步骤。 例如,如果我的用户是Hugo并且他发送了Hey:
Sending hugo: hey
to System.Net.Sockets.TcpClient0
Sending hugo: hey
to System.Net.Sockets.TcpClient1
消息被重定向到连接到我服务器的所有用户。现在问题出在客户端上,由于某些原因,该消息仅显示在最后连接的用户上。考虑前面的示例,消息“ Hey”将在TcpClient1上两次显示,并且在TcpClient0上不显示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using ConsoleApp1;
namespace ServerSide
{
class Server
{
private int port;
private byte[] buffer = new byte[1024];
public delegate void DisplayInvoker(string t);
private StringBuilder msgclient = new StringBuilder();
private TcpListener client;
static IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
private IPAddress ipAddress = host.AddressList[0];
private TcpClient myclient;
private List<TcpClient> usersConnected = new List<TcpClient>();
public Server(int port)
{
this.port = port;
}
public void startServer()
{
client = new TcpListener(ipAddress, port);
client.Start();
SERV a = new SERV();
a.Visible = true;
a.textBox1.AppendText("Waiting for a new connection...");
while (true)
{
myclient = client.AcceptTcpClient();
usersConnected.Add(myclient);
a.textBox1.AppendText("New User connected @" + myclient.ToString() );
myclient.GetStream().BeginRead(buffer, 0, 1024, Receive, null);
a.textBox1.AppendText("Size of List " + usersConnected.Count);
}
}
private void Receive(IAsyncResult ar)
{
int intCount;
try
{
lock (myclient.GetStream())
intCount = myclient.GetStream().EndRead(ar);
if (intCount < 1)
{
return;
}
Console.WriteLine("MESSAGE RECEIVED " + intCount);
BuildString(buffer, 0, intCount);
lock (myclient.GetStream())
myclient.GetStream().BeginRead(buffer, 0, 1024, Receive, null);
}
catch (Exception e)
{
return;
}
}
public void Send(string Data)
{
lock (myclient.GetStream())
{
System.IO.StreamWriter w = new System.IO.StreamWriter(myclient.GetStream());
w.Write(Data);
w.Flush();
}
}
private void BuildString(byte[] buffer, int offset, int count)
{
int intIndex;
for (intIndex = offset; intIndex <= (offset + (count - 1)); intIndex++)
{
msgclient.Append((char)buffer[intIndex]);
}
OnLineReceived(msgclient.ToString());
msgclient.Length = 0;
}
private void OnLineReceived(string Data)
{
int i = 0;
foreach (TcpClient objClient in usersConnected)
{
Console.WriteLine("Sending " + Data + " to " + objClient + i);
Send(Data);
i++;
}
}
}
}
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 WindowsFormsApp2
{
public partial class Form2 : Form
{
private delegate void DisplayInvoker(string t);
private string currentTopic = null;
private StringBuilder msg = new StringBuilder();
static public string MyUser { get; set; }
static private byte[] buffer = new byte[1024];
static IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
static IPAddress ipAddress = host.AddressList[0];
static Client user = new Client(MyUser, ipAddress, 136);
public Form2(string User) // when a user is logged in , directly connect him to the server
{
InitializeComponent();
MyUser = User;
user.clientConnection();
Thread readingg = new Thread(reading);
readingg.Start();
user.sendText(MyUser + " joined the chatroom!" +"\n");
IPAdress.Text = GetLocalIP(host);
IPAdress.ReadOnly = true;
}
public void reading()
{
user.getClient().GetStream().BeginRead(buffer, 0, 1024, ReadFlow, null);
Console.WriteLine("READING FUNCTION TRIGGERED FOR "+MyUser);
}
private void DisplayText(string t)
{
UserChat.AppendText(t);
Console.WriteLine("DISPLAY FUNCTION TRIGGERED FOR " + MyUser + "with " +msg.ToString());
}
private void BuildString(byte[] buffer,int offset, int count)
{
int intIndex;
for(intIndex = offset; intIndex <= (offset + (count - 1)); intIndex++)
{
if (buffer[intIndex] == 10)
{
msg.Append("\n");
object[] @params = { msg.ToString() };
Console.WriteLine("BUILDSTIRNG FUNCTION TRIGGERED FOR " + MyUser);
Invoke(new DisplayInvoker(DisplayText),@params);
msg.Length = 0;
}
else
{
msg.Append((char)buffer[intIndex]);
}
}
}
private void ReadFlow(IAsyncResult ar)
{
int intCount;
try
{
intCount = user.getClient().GetStream().EndRead(ar);
Console.WriteLine(intCount);
if (intCount < 1)
{
return;
}
Console.WriteLine(MyUser + "received a message");
BuildString(buffer, 0, intCount);
user.getClient().GetStream().BeginRead(buffer, 0, 1024, this.ReadFlow, null);
}catch(Exception e)
{
return;
}
}
private string GetLocalIP(IPHostEntry host)
{
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
return "192.168.1.1";
} // get your local ip
private void label1_(object sender, EventArgs e)
{
this.Text = "Hello " + MyUser;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void UserMessage_TextChanged(object sender, EventArgs e)
{
}
private void UserMessage_Focus(object sender, EventArgs e)
{
UserMessage.Text = "";
}
private void UserMessage_Focus2(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
listBox1.Items.Add(addTopic.Text);
addTopic.Text = "Add Topic";
}
private void button2_(object sender, EventArgs e)
{
}
private void addTopic_(object sender, EventArgs e)
{
}
private void addTopic_TextChanged(object sender, EventArgs e)
{
}
private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
string curItem = listBox1.SelectedItem.ToString();
label1.Text = "Topic "+curItem;
currentTopic = curItem;
}
private void IPAdress_TextChanged(object sender, EventArgs e)
{
}
// send msg to the server
private void UserChat_TextChanged(object sender, EventArgs e)
{
}
private void Form2_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
//Handle event here
System.Windows.Forms.Application.Exit();
}
private void Send_Click_1(object sender, EventArgs e)
{
user.sendText(MyUser + ": " + UserMessage.Text +"\n");
UserMessage.Text = " ";
}//send message
}
}
答案 0 :(得分:2)
在OnLineReceived
中,对于每个呼叫SendData
的客户,您都将其发送到myclient
。您可能想将objClient
传递到SendData
中,然后发送给那个。
请注意,那里也存在一些线程问题;例如,如果某人恰好在您访问列表时连接,则它将中断迭代器。