C# 尝试创建一个可以写入控制台或窗体应用程序的方法
我在一个通用服务器和一个客户端程序上工作。我面临的问题是,当我在客户端和服务器的OnDataReceived中时,我不知道如何处理数据。理想情况下,它应该将接收到的数据输出到一个窗口中,但我不知道它是表单应用程序还是控制台应用程序。所以问题是我如何创建一个可以同时处理这两个问题的通用方法,或者如果不可能,我应该怎么做 我正在使用的代码:C# 尝试创建一个可以写入控制台或窗体应用程序的方法,c#,client,client-server,C#,Client,Client Server,我在一个通用服务器和一个客户端程序上工作。我面临的问题是,当我在客户端和服务器的OnDataReceived中时,我不知道如何处理数据。理想情况下,它应该将接收到的数据输出到一个窗口中,但我不知道它是表单应用程序还是控制台应用程序。所以问题是我如何创建一个可以同时处理这两个问题的通用方法,或者如果不可能,我应该怎么做 我正在使用的代码: SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
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;
}
}
附言。
我不知道是否需要知道,但我正在做异步客户机/服务器。我将创建一个接口,可以在其中写入事件信息,比如IEventink。因此OnDataReceived与IEventSink实例一起工作,并对其调用Write方法。
然后我将有两个接口实现:一个在控制台上写,另一个在表单上写。您的通信类不应该关心它们接收的数据发生了什么。相反,它们应该使数据可供需要它的类使用。一种方法是提供一个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);
}
}
}
在listener类中:
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);
}
}
你可以尝试实施战略
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);
希望它有助于用字符串触发事件?如果数据缓冲区字符串是套接字对象的一个成员,我会提供帮助-然后您可以仅使用套接字对象触发事件&您的事件处理程序(不管结果如何)将拥有决定如何处理数据所需的一切 Rgds,
Martin这是一个很好的依赖注入位置
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元素不知道或不关心数据从何而来,工作进程也不知道或不关心数据从何而来。。。它是“松散耦合”的。您是要创建一个程序来执行特定的功能,还是要创建一个可重用的库?不确定“通用服务器和客户端程序”是什么意思。您可以看看MVP模式。演示者将只使用视图的方法来显示数据,视图将考虑是否在控制台、窗体或html标签中显示。好的,我应该包括SocketPacket类(我现在有)它确实有DataBuffer。但是,您能否给出一个事件处理程序的外观示例,以及我如何创建事件。据我所知,我从未使用过它们。好吧,我不确定我将如何创建这样的活动。不要认为我使用过(自定义)事件,所以任何(模拟)示例都会很好。我不太确定这是如何工作的,也就是说,这会是我的客户机和服务器类的一部分吗?如果是这样,OnDataReceived会调用GetSomeData吗?可能是我完全误解了这一点。上面的类可能是客户机类和服务器类中的一个(或两个)。您只需像平常一样处理通信代码,然后在接收数据时引发事件(如上所示),以便侦听器可以对数据进行处理。我将更新示例以显示侦听器。好的,如果我理解正确的话。我只是使用szData而不是stringData。那么MyListener是使用我的服务器/客户机的任何程序(无论是窗体还是控制台应用程序)的一部分,并且将在代理中放置新数据时触发?另外,void方法MyListener应该是MyListenerMethod还是?是的,它应该是MyListenerMethod。这是基本思想,是的:允许其他类侦听数据,并让客户机/服务器告诉他们数据何时到达。