我正在开发一般服务器和客户端程序。我面临的问题是当我在我的客户端和服务器中的OnDataReceived时,我不知道如何处理数据。理想情况下,它应该将接收的数据输出到窗口中,但我不知道它是否是Form或Console应用程序。所以问题是如何创建一个可以处理两者的通用方法,或者如果不可能,我应该做什么呢?
我正在使用的代码:
SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
int iRx = theSockId.m_currentSocket.EndReceive(asyn);
char[] chars = new char[iRx + 1];
Decoder decode = Encoding.Default.GetDecoder();
int charLength = decode.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0);
String szData = new String(chars);
//Handle Message here
WaitForData();
套接字包类:
class SocketPacket
{
public Socket m_currentSocket;
public byte[] dataBuffer = new byte[1024];//Buffer to store the data by the client
public SocketPacket(Socket socket)
{
m_currentSocket = socket;
}
}
PS。 我不知道是否需要知道,但我正在做异步客户端/服务器。
答案 0 :(得分:3)
您的沟通课程不应该关心他们收到的数据会发生什么。相反,他们应该将数据提供给想要它的类。一种方法是提供getData()方法,该方法接收数据然后将其返回给调用者。更好的方法是提供DataArrived事件,每当您收到数据时都会触发该事件。这样,任何数量的消费者都可以收听数据,但是您的通信代码不必知道哪些类正在收听,或者他们打算如何处理数据。
修改强>:
一个简单的例子:
public class MyClassWithEvent
{
public delegate void DataArrivedDelegate(string data);
public event DataArrivedDelegate DataArrived;
public void GetSomeData()
{
// Communication code goes here; stringData has the data
DataArrivedDelegate handler = DataArrived;
if (handler != null)
{
// If you want to raise the event on this thread, this is fine
handler(stringData);
}
}
}
在你的听众课程中:
public MyListener
{
public MyListener(MyServer server)
{
// Sets MyListenerMethod to be called when DataArrived is raised
server.DataArrived += MyListenerMethod;
}
public void MyListenerMethod(string data)
{
// Do something with the data
Console.WriteLine(data);
}
}
答案 1 :(得分:2)
使用字符串触发事件?如果数据缓冲区字符串是套接字对象的成员,我会帮助你 - 然后你可以只使用套接字对象&你的事件处理程序,无论结果如何,都将拥有决定如何处理数据所需的一切。
RGDS, 马丁
答案 2 :(得分:1)
我会创建一个可以编写事件信息的界面,比如IEventSink。因此OnDataReceived与IEventSink实例一起工作并在其上调用Write方法。 然后我将有2个接口实现:一个在控制台上写,另一个在表单上写。
答案 3 :(得分:1)
您可以尝试实施策略
interface IOutputStrategy
{
void Output(string message);
}
class ConsoleOutput:IOutputStrategy
{
public void Output(string message)
{
Console.Writeline(message);
}
}
class FormOutput:IOutputStrategy
{
public void Output(string message)
{
// output where you want
}
}
在服务器/客户端上,您将获得IOutputStrategy
//Server
IOutputStrategy instance = new ConsoleOutput();
//Client
IOutputStrategy instance = new FormOutput();
然后在OnDataReceived回调中,您可以使用当前的IOutputStrategy实例来输出消息
instance.Output(szData);
希望有所帮助
答案 4 :(得分:0)
这是依赖注入的好位置。
将您的工作流程更改为接受对您的工作人员功能的引用,并让它在需要的地方发送响应。
protected void getResults(ISiemsen siemens ... )
{
SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
int iRx = theSockId.m_currentSocket.EndReceive(asyn);
char[] chars = new char[iRx + 1];
Decoder decode = Encoding.Default.GetDecoder();
int charLength = decode.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0);
String szData = new String(chars);
WaitForData();
//Handle Message here
siemsen.ShowTheResult(theResult);
}
使用这种技术,UI元素不知道或关心数据来自何处,而工作者进程不知道或关心去哪里......它是“松散耦合”。