从现在开始,我试图在c#中学习Socketing编程。我一直在寻找许多msdn,stackoverflow和代码项目项目,讨论和示例。
我重写了它们,我使用了调试和"步骤-in"在Visual Studio中,我一行一行地接受了它,现在我正在进行我的小项目。"这是一个迷你聊天(控制台应用程序)。让我来描述代码,在底部我会告诉你我的问题。
服务器
主:
我已经启动了一个服务器,一个TcpListener
在ip 0.0.0.0和端口8000上。
我已经在接受我的客户端的方法上创建了一个线程(使用了3个线程,这是其中之一,第一个)并启动它。
方法接受客户:
我已使用TcpClient
接受TcpListener
中while(true)
的Tcp客户端。
我已从该客户端获取了该流,并且我已在该流上创建了一个streamReader和一个streamWriter。
我已经创建了第二个帖子,我已经完成了写作的逻辑。
我已经盯着巫婆的第三个帖子,我已经完成了阅读的逻辑。
以下是代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TcpServer
{
class TcpServer
{
static TcpListener tcpL;
static TcpClient tcpC;
static NetworkStream nStream;
static StreamWriter sW;
static StreamReader sR;
static List<TcpClient> lTcp;
static void Main(string[] args)
{
Console.WriteLine(" >> Server Started");
tcpL = new TcpListener(IPAddress.Parse("0.0.0.0"), 8000);
tcpL.Start();
Thread accClients = new Thread(acceptClients);
int counter = 0;
accClients.Start(counter);
Console.ReadLine();
}
private static void acceptClients(object obj)
{
while (true)
{
tcpC = tcpL.AcceptTcpClient();
Console.WriteLine(" >> Client Connected");
nStream = tcpC.GetStream();
sW = new StreamWriter(nStream);
sR = new StreamReader(nStream);
Console.WriteLine(" >> Data Transfer Established");
Thread thWrite = new Thread(doWriteing);
thWrite.Start(sW);
Thread thRead = new Thread(doReading);
thRead.Start(sR);
}
}
private static void doWriteing(object obj)
{
StreamWriter sW = (StreamWriter)obj;
while (true)
{
sW.WriteLine(Console.ReadLine());
sW.Flush();
}
}
private static void doReading(object obj)
{
StreamReader sR = (StreamReader)obj;
while (true)
{
string linie;
try
{
linie = sR.ReadLine();
Console.WriteLine(linie);
}
catch (Exception)
{
continue;
}
}
}
}
}
和客户:
这个很简单。
主:
我在ip 127.0.0.1和端口8000上连接了TcpClient
。
我已经从TcpClient
获得了流。
在该流上创建了StreamWriter
和StreamReader
。
开始写作和阅读2个主题。
以下是代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TCPClient
{
class TCPClient
{
static TcpClient tcpC;
static NetworkStream nStream;
static void Main(string[] args)
{
Console.WriteLine(" >> Client Started");
tcpC = new TcpClient("127.0.0.1", 8000);
Console.WriteLine(" >> Client Connected");
nStream = tcpC.GetStream();
StreamWriter sW = new StreamWriter(nStream);
StreamReader sR = new StreamReader(nStream);
Thread thWrite = new Thread(doWriteing);
thWrite.Start(sW);
Thread thRead = new Thread(doReading);
thRead.Start(sR);
Console.ReadLine();
}
private static void doWriteing(object obj)
{
StreamWriter sW = (StreamWriter)obj;
while (true)
{
sW.WriteLine(Console.ReadLine());
sW.Flush();
}
}
private static void doReading(object obj)
{
StreamReader sR = (StreamReader)obj;
while (true)
{
string linie;
try
{
linie = sR.ReadLine();
Console.WriteLine(linie);
}
catch (Exception)
{
continue;
}
}
}
}
}
现在我有三大问题:
服务*(发送)
> >> Server Started
> >> Client Connected
> >> Data Transfer Established
> >> Client Connected
> >> Data Transfer Established
> >> Client Connected
> >> Data Transfer Established
.
1
2
3
4
5
6
客户端1 (接收)
>> Client Started
>> Client Connected
1
4
客户端2 (接收)
>> Client Started
>> Client Connected
2
5
客户端3 (接收)
>> Client Started
>> Client Connected
3
6
如何将服务器收到的数据发送给所有客户?
我如何存储它们?究竟要存储(以及什么)能够通知服务器此客户端ID想要将数据发送到X客户端ID。 (例如:客户1想说&#34;我在沙滩上&#34;到客户3和&#34;我在家&#34;到客户2)
/ *我知道可能会出现很多因为我没有编程如此防守,但现在我只想学习并且对我来说任何可能出现的例外都有帮助。而且我知道Flush的第一个流不会到达,但在这种情况下我可能做错了,因为我正在调查这个问题。 * /
/ *值得一提的是:客户只与服务器聊天,他们不会看到其他客户写的内容。并且服务器以正确的顺序接收数据* /
P.S。如果您对此问题感兴趣,请使用此代码。我来到这里是因为我想学习这些东西不是因为我搜索了另一个&#34;技巧&#34;或者只是解决它。
答案 0 :(得分:0)
当客户端连接到服务器时,将客户端添加到集合中。当服务器接收到需要传递给所有其他连接客户端的数据时,迭代客户端集合并向其发送数据。您需要检查客户端是否仍然连接。向所有连接的客户端广播消息比私有消息传递更容易。您只需将消息从一个客户端重播到所有客户端,如上所述。对于私人消息传递,客户端需要向服务器发送命令,这表明客户的意图。例如,一个简单的命令可能是
发送&#34;你好约翰&#34;致客户3
答案 1 :(得分:0)
我会尽力回答这些问题:
首先,您应该在代码中正确添加更多调试消息,因为这将极大地帮助您理解该过程。这是一个pastebin,我修改了你的代码以包含更多的消息,这样你就可以更好地理解读/写的内容。
服务器为什么或者可能“如何”将数据发送到每个线程(到 一次只有一个线程)按照它们的创建顺序?请 向我解释一下,我真的很想了解这个过程。这里有一个 “样本”(似乎我无法发布图片):
服务器不向每个线程发送数据。它将数据发送到由tcpC.GetStream()
检索的Streams。在acceptClients
函数中,您将获得该特定客户端(连接的客户端)的网络流。然后,将这些传递给您创建的新线程。然后,每个读/写线程对都可以访问自己的NetworkStream
以便与客户端一起工作。
您被混淆的原因是因为您使用其他客户端的值覆盖tcpC
和nStream
。变量tcpC
和nStream
应该是一个List。对于连接的每个客户端,有TcpClient
和NetworkStream
。
换句话说。在服务器上,对于您运行的每个客户端,有1 TcpClient
,1 NetworkStream
和2 Threads
。
如何将服务器收到的数据发送给所有客户端?
您要做的是向所有客户收到的广播信息(如聊天程序)。为此,您需要List<string>
作为缓冲区。您将在doReading
函数中的服务器上读取一个列表(缓冲区),它将存储您从客户端读取的内容。然后,您将使用doWriteing
函数将该列表写入客户端。您还需要一种方法来确保服务器向所有客户端发送消息(而不仅仅是其中一个消息)。
客户1希望向客户3说“我在沙滩上”
为此,您需要一种以命令行格式说明的方法。像
这样的东西SEND ID TEXT
ID
是您希望发送的客户端#,其后是消息。然后,您还可以使用BROADCAST TEXT
之类的内容向所有客户广播。
再次使用Pastebin链接:http://pastebin.com/SBjc6tBF