2010-03-16 43 views
2

有没有办法处理与C#中的套接字会话?我的问题与会话的.NET TCP套接字

例子:
我有一个socket监听端口5672。

TcpListener socket = new TcpListener(localAddr, 5672); 
socket.Start(); 
Console.Write("Waiting for a connection... "); 

// Perform a blocking call to accept requests. 
TcpClient client = socket.AcceptTcpClient(); 
Console.WriteLine("Connected to client!"); 

,我有两个客户端将发送一个字节的服务器。客户端A发送0x1,客户端B发送0x2。 从服务器端,我读这个数据是这样的:

Byte[] bytes = new Byte[256]; 
String data = null; 

NetworkStream stream = client.GetStream(); 
while ((stream.Read(bytes, 0, bytes.Length)) != 0) 
{ 
    byte[] answer = new ... 
    stream.Write(answer , 0, answer.Length); 
} 

然后客户端A发送为0x11。 我需要一种方法来知道这个客户端是以前发送“0x1”的相同。

回答

4

每个TcpClient实例用于不同的连接。 TCP中的连接由四部分组成:源IP,源端口,目标IP,目标端口。因此,即使您拥有相同的目标IP和端口,以及相同的源端口,您也有两个不同的连接。

一个客户端发送的数据不会与其他客户端发送的数据混合在一起。客户端在连接上发送的数据将按照该连接顺序接收。

Sessions成为问题的唯一时间是在连接关闭后记住客户端。

+0

我不明白数据如何混合。在我读取第一个客户端发送的数据后,TcpClient对象被销毁。并读取以下数据我必须做socket.AcceptTcpClient();再次。你能发布一个演示代码来检测客户端A在sendig 0x1后发送0x11的时间吗?谢谢 – 2010-03-16 19:39:10

+0

@ZeCarlos:你真的需要关闭'TcpClient'实例吗?为什么不重用它们?每个人都可以从一个客户端获得一个完整的数据流。 – 2010-03-16 19:43:29

+0

你说得对。我可以重用TcpClient及其关联的流。对不起,我的无知。谢谢 – 2010-03-16 20:09:30

0

您可能需要实施自己的协议以识别客户端。也许定义一个字节块,除了数据外,还包含一个客户端标识符。

+0

感谢您的回答,但我不能那样做。我正在实现一个通过TCP进行通信的协议。我无法修改客户发送的信息。 – 2010-03-16 19:12:29

+0

@ZeCarlos:谁定义客户端发送的数据格式? – 2010-03-16 19:16:00

+0

其协议。 AMQP就是这种情况。 http://www.amqp.org/confluence/download/attachments/720900/amqp0-9.pdf?version = 1&modificationDate = 1183135701000 但是,帧中的数据没有任何字段标识客户端。我通过了解客户端使用的IP和端口来识别。我正在寻找一些自动完成的方法 – 2010-03-16 19:25:31

0

您需要某种认证或预先协商的令牌,并且所有这些都用某种盐加密。

+1

你当然不需要任何盐渍哈希或加密的身份识别手段,但取决于特定的需求,它可能会被推荐。 – 2010-03-16 19:12:15

1

关于如何在Web世界(HTTP)中实现会话的现有文献很多。

一个关键是你是关闭客户端连接还是持久性?如果它们是持久的,那么只需通过它们的对象引用来标识它们。如果不是,则...

1)您可以根据源IP地址进行简单会话。但是,如果多个客户端位于NAT防火墙之后,共享IP,那么这不起作用,请参阅下一个选项。

2)使用一个“cookie”

3)使用身份验证,以确定每个客户

每个选项除了基于IP的会话需要添加一些东西到协议本身。

有些事情要记住套接字。远程IP +远程端口唯一标识客户端TCP套接字。来自同一个远程客户端的多个连接将具有不同的远程端口。但是,如果套接字关闭,则不能依赖该套接字,因为远程操作系统可能会在新旧连接超时后重新启动远程端口以建立新连接。