visus
Grünschnabel
Hi,
Nachdem ich etwa 2 Wochen lang das Netz durchsucht habe um eine funktionierende Methode zu finden, bin ich nun hier gelandet.
Ich habe einen Server (in C geschrieben), der mit den Clients C structs austauscht. (Das Endianesproblem spielt z.Zt. keine Rolle, soweit nutzen alle Systeme die Network Byte Order, also Big Endian) Die bisherigen Clients agieren eher als Agenten, die auf den Systemen Updates fahren und die Systeme auf dem selben Stand halten. Soweit funktioniert das alles. Nun bin ich dabei einen Client zu schreiben, mit dem ich die Updateinformationen zum Server gelangen koennen. Ich habe also folgende Topologie:
Soweit die Theorie:
Das C struct, das ich verwende sieht in etwa so aus:
So empfangen die Clients und der Server die structs:
Und so werden sie gesendet:
Und jetzt kommt das Problem:
Die C# structs sind nicht so einfach zu senden/empfangen. Ich habe duzende Marshalingmethoden ausprobiert... Vergebens.
Ich packe mal die aktuelle Socket class, die ich angefangen habe ans Ende des Posts. Im Source sind noch einige Ueberreste aus vergeblichen Versuchen ... Ich habe sie jetzt mal drin gelassen um vermeindliche Loesungsvorschlaege, die ich bereits getestet habe zu demonstrieren um somit die Loesung des Problems zu beschleunigen.
Ich hoffe das bekommt einer von euch gebacken. Ich habe damit schon sehr viele Nerven verloren.
Danke schonmal,
visus
Nachdem ich etwa 2 Wochen lang das Netz durchsucht habe um eine funktionierende Methode zu finden, bin ich nun hier gelandet.
Ich habe einen Server (in C geschrieben), der mit den Clients C structs austauscht. (Das Endianesproblem spielt z.Zt. keine Rolle, soweit nutzen alle Systeme die Network Byte Order, also Big Endian) Die bisherigen Clients agieren eher als Agenten, die auf den Systemen Updates fahren und die Systeme auf dem selben Stand halten. Soweit funktioniert das alles. Nun bin ich dabei einen Client zu schreiben, mit dem ich die Updateinformationen zum Server gelangen koennen. Ich habe also folgende Topologie:
Die Informationen, die der Server vom Controller empfaengt werden unbehandelt an die Clients gesendet. Folgende Topologie funktioniert nicht:Clients <--> Server <--> Controller
Das liegt daran, dass die Clients nicht zeitgleich mit dem Controller verbunden sind, da sie auch mal aus sein koennen. Der Controller sendet also das struct an den Server und der wartet auf die Clients und verpasst denen dann die Updatespritze. Wie gesagt: Die Client <--> Server-Kommunikation funktioniert.Clients <--> Controller
Soweit die Theorie:
Das C struct, das ich verwende sieht in etwa so aus:
PHP:
struct packet_t
{
/* type: dient zur Unterscheidung von Client und Controller */
int type;
/* checksum: sie wird aus dem body mit einem *geheimen*
* Algorithmus generiert und dient der Abwehr von
* Man-in-the-Middle-Attacken o.ae. */
int checksum;
/* body: enthaelt die Updateinformationen (XML) */
char body[1024];
};
PHP:
/* ... */
struct packet_t packet;
memset(&packet, 0, sizeof(struct packet_t));
if (0 >= recv(client.sock.s, (char *) &packet, sizeof(struct packet_t), 0))
return 0;
/* ... */
PHP:
/* ... */
if (0 >= send(client.sock.s, (char *) &packet, sizeof(struct packet_t), 0))
return 0;
/* ... */
Die C# structs sind nicht so einfach zu senden/empfangen. Ich habe duzende Marshalingmethoden ausprobiert... Vergebens.
Ich packe mal die aktuelle Socket class, die ich angefangen habe ans Ende des Posts. Im Source sind noch einige Ueberreste aus vergeblichen Versuchen ... Ich habe sie jetzt mal drin gelassen um vermeindliche Loesungsvorschlaege, die ich bereits getestet habe zu demonstrieren um somit die Loesung des Problems zu beschleunigen.
Ich hoffe das bekommt einer von euch gebacken. Ich habe damit schon sehr viele Nerven verloren.
Danke schonmal,
visus
PHP:
struct Packet
{
public Int32 Type;
public Int32 Checksum;
public String Body;
}
class Socket
{
private StreamReader clientStreamReader;
private StreamWriter clientStreamWriter;
// LPStr, LPWStr, LPTStr, BStr, TBStr, VBByRefStr oder AnsiBStr
[DllImport("struct.dll")]
private static extern void StructToCharArr(int Type, int Checksum, char[] Body, [MarshalAs(UnmanagedType.LPStr)] out string Output);
public Socket()
{
/* Nothing to do, yet */
}
public bool ConnectToServer(string IPAddress, Int32 Port)
{
try
{
TcpClient tcpClient = new TcpClient(IPAddress, Port);
NetworkStream clientSockStream = tcpClient.GetStream();
this.clientStreamReader = new StreamReader(clientSockStream);
this.clientStreamWriter = new StreamWriter(clientSockStream);
}
catch (Exception e)
{
//cForm.addListBoxItem(e.Message);
MessageBox.Show(e.Message);
return false;
}
return true;
}
public static byte[] SerializeExact(object anything)
{
int structsize = Marshal.SizeOf(anything);
IntPtr buffer = Marshal.AllocHGlobal(structsize);
Marshal.StructureToPtr(anything, buffer, false);
byte[] streamdatas = new byte[structsize];
Marshal.Copy(buffer, streamdatas, 0, structsize);
Marshal.FreeHGlobal(buffer);
return streamdatas;
}
public static byte[] StrToByteArray(string str)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
return encoding.GetBytes(str);
}
public bool Send()
{
Packet packet;
Checksum cs = new Checksum();
string packetC;
packet.Type = 2;
packet.Checksum = cs.GenerateChecksum("");
packet.Body = "";
StructToCharArr(packet.Type, packet.Checksum, "test".ToCharArray(), out packetC);
this.clientStreamWriter.WriteLine(packetC);
MessageBox.Show(packetC);
this.clientStreamWriter.Flush();
return true;
}
}