Avatar billede ghorfraq Nybegynder
30. september 2003 - 14:51 Der er 21 kommentarer og
1 løsning

Socket, Objekter

HEjsa

Jeg har en class Packet indeholdende nogle instansvariabler og dertilhørende get/set metoder. denne klasses instantieres i et objekt som skal sendes over netværk via stream sockets. Hvordan lader dette sig gøre, når man kun kan kan sende byte[]. med andre ord. Hvordan konverterer man en hel klasse til et byteArray så det kan sendes med sockets? Og hvordan konverterer man det tilbage igen efter modtagelse på destinationen?
Avatar billede arne_v Ekspert
30. september 2003 - 20:22 #1
Eksempel på konvertering mellem object og byte[]:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
public class X
{
    private int v;
    public int V
    {
        get
        {
            return v;
        }
        set
        {
            v = value;
        }
    }
   
}

class MainClass
{
    public static byte[] Object2ByteArray(Object o)
    {
        MemoryStream ms = new MemoryStream();
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(ms, o);
        return ms.ToArray();
    }
    public static object ByteArray2Object(byte[] theByteArray)
    {
        MemoryStream ms = new MemoryStream(theByteArray);
        BinaryFormatter bf = new BinaryFormatter();
        ms.Position = 0;
        return bf.Deserialize(ms);
    }
    public static void Main(string[] args)
    {
        X x1 = new X();
        x1.V = 123;
        Console.WriteLine(x1.V);
        byte[] b = Object2ByteArray(x1);
        X x2 = (X)ByteArray2Object(b);
        Console.WriteLine(x2.V);
    }
}
Avatar billede ghorfraq Nybegynder
01. oktober 2003 - 07:33 #2
Jeg har leget med et lignende eksempel og kan konstatere det fungerer. MEn min fejl må da skyldes en anden ting. Du skal nok få point da du har besvaret mit spørgsmål, men håber du er interesseret i at komme med et byd på fejlen.
Avatar billede ghorfraq Nybegynder
01. oktober 2003 - 07:37 #3
jeg har en SocketServer og en SocketClient. Disse befinder sig i henholdsvis namespace TidsurServer og namespace SimpleClient. Objektet (class Packet) bliver serialiseret fint og afsendt. Men ved modtagelse får jeg følgende fejl når jeg prøver at tilgå objektet med:
Console.WriteLine("ClientID " + packet.IClientId + " PAcketID " + packet.IPacketID + " Command " + packet.SCommand + " UserName " + packet.SUserName + "HostName " + packet.SHostName + " kort " + packet.IKort
+ " Nummer " + packet.INummer);
Avatar billede arne_v Ekspert
01. oktober 2003 - 07:37 #4
Hvilken fejl får du ?
Avatar billede ghorfraq Nybegynder
01. oktober 2003 - 07:37 #5
Fejl:
Serialization Error occured! :Cannot find the assembly simpleClient, Version=1.0.1369.11748, Culture=neutral, PublicKeyToken=null.
Packet received!
An unhandled exception of type 'System.NullReferenceException' occurred in TidsurServer.exe
Avatar billede ghorfraq Nybegynder
01. oktober 2003 - 07:39 #6
ved godt min kode lugter lidt af java-syntax ;-)
Avatar billede ghorfraq Nybegynder
01. oktober 2003 - 07:44 #7
linien packet received er bare min udskrivning til konsollen. så pakken burde blive modtaget. Men tjaah.....
Avatar billede arne_v Ekspert
01. oktober 2003 - 07:58 #8
Java er ikke noget problem.

:-)

Umiddelbart lyder det som om at server ikke har adgang til koden.
Avatar billede arne_v Ekspert
01. oktober 2003 - 07:59 #9
Eller måske en forkert version.
Avatar billede ghorfraq Nybegynder
01. oktober 2003 - 09:04 #10
jeg smider lige noget eksempel socket kode ind, hvis du har tid til at kigge på det
Avatar billede ghorfraq Nybegynder
01. oktober 2003 - 09:06 #11
client:

using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public class Client
{
    public void clientRunning()
    {
        int ANYPORT = 0;
        const int    SAMPLETCPPORT = 9999;   

        //Create a TCP socket.
        Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPHostEntry localHostEntry = Dns.GetHostByName("sbm");

        //Bind the client to any local port chosen by the kernel.
        IPEndPoint localIpEndPoint = new IPEndPoint(localHostEntry.AddressList[0], ANYPORT);
               
        soc.Bind(localIpEndPoint);
               
        IPHostEntry remoteHostEntry = Dns.GetHostByName("sbm");
               
        //Identify and connect to the remote endpoint.
        IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Parse("EN IPDADRESSE!!!!!!!!!!!!!"), SAMPLETCPPORT);
                   
        soc.Connect(remoteIpEndPoint);                               
                       

        //Packet containing LogIn Information
        // create a packet so the client gets its ID. A packet ID of 1
        //indicates that the stream is sent from client
        Packet packet = new Packet( -1, 1, "login", "sbm", "sbm", 1, 2);
        Console.WriteLine("Sending Packet To :" + soc.RemoteEndPoint);
               
        //Convert Packet to ByteStream
        byte[] byteToBeSent = Object2ByteArray(packet);
        Packet p1 = (Packet)ByteArray2Object(byteToBeSent);
       
        //Just checking that the Object2ByteArray Method actually works               
        Console.WriteLine("ClientID :" + p1.IClientId);

        int nBytesSent = soc.Send( byteToBeSent, byteToBeSent.Length, SocketFlags.None);

        //Send the message to the remote endpoint.               
        Console.WriteLine("Bytes sent :" + nBytesSent);           
           
               
        }
   
    public static byte[] Object2ByteArray(Object o)
    {
        MemoryStream ms = new MemoryStream();
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(ms, o);
        return ms.ToArray();
    }

    public static object ByteArray2Object(byte[] theByteArray)
    {
        MemoryStream ms = new MemoryStream(theByteArray);
        BinaryFormatter bf = new BinaryFormatter();
        ms.Position = 0;
        return bf.Deserialize(ms);
    }
        }
Avatar billede ghorfraq Nybegynder
01. oktober 2003 - 09:07 #12
Server:
using System;
using System.Threading;
using System.Globalization;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

    class Server
    {                       
            //Network Variables
            private const int        port = 9999;       
            private Socket            soc;
            private Socket            acceptSocket;
            //System variables
            private Packet            packet;       
                   

           
            public void serverRunning()
            {   
                byte[] received = new byte[1024];                                                               
                //initialising listenSocket
                soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
               
                //making endpoint to bind to
                IPEndPoint localIpEndPoint = new IPEndPoint(IPAddress.Parse("EN IPADRESSE!!!!!!!!!"), port);
                               
                //binding               
                soc.Bind(localIpEndPoint);                                               

                //Listening for client connections
                soc.Listen(10);                       
               
                Console.WriteLine("Server is listening for Client Connection Attempts");
                Console.WriteLine("");
                                   
                acceptSocket = soc.Accept();

                Console.WriteLine("Client connected!");                                           

                int bytesReceived = acceptSocket.Receive(received, acceptSocket.Available, SocketFlags.None);
               
                try
                {
                    packet = (Packet)ByteArray2Object(received);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Serialization Error occured! :" + e.Message);
                }
                Console.WriteLine("Packet received!");
               
                //trying to print clientID from received Packet
                try
                {
                    Console.WriteLine("ClientID :" + packet.IClientId);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Cannot print ClientID! :" + e.Message);
                }
            }
   
            public static byte[] Object2ByteArray(Object o)
            {
                MemoryStream ms = new MemoryStream();
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(ms, o);
                return ms.ToArray();
            }

            public static object ByteArray2Object(byte[] theByteArray)
            {
                MemoryStream ms = new MemoryStream(theByteArray);
                BinaryFormatter bf = new BinaryFormatter();
                ms.Position = 0;
                return bf.Deserialize(ms);
            }
        }
Avatar billede ghorfraq Nybegynder
01. oktober 2003 - 09:08 #13
Packet:

using System;

    [Serializable]
    public class Packet
    {
        private int        iClientId = -1;
        private int        iPacketId = -1;
        private string  sCommand;
        private string  sUserName;
        private string  sHostName;
        private int        iKort;
        private int        iNummer;
        private byte[]    byteBuffer = null;
       
        public Packet(int iClientID, int iPacketID, string sCommand,
            string sUserName, string sHostName,int iKort, int iNummer)
        {
            this.iClientId = iClientID;
            this.iPacketId = iPacketID;
            this.sCommand = sCommand;
            this.sUserName = sUserName;
            this.sHostName = sHostName;
            this.iKort = iKort;
            this.iNummer = iNummer;               
        }
       
        public int INummer
        {   
            get
            {
                return this.iNummer;               
            }           
        }
       
   
       
        public int IKort
        {
            get
            {
                return this.iKort;
            }
        }   

        public string SUserName
        {
            get
            {
                return this.sUserName;
            }
        }
       
        public string SHostName
        {
            get
            {
                return this.sHostName;
            }
        }

        public string SCommand
        {
            get
            {
                return this.sCommand;
            }
        }

        public int IClientId
        {
            get
            {
                return this.iClientId;
            }
        }
       
        public int IPacketID
        {
            get
            {
                return this.iPacketId;
            }
        }

        public byte[] ByteBuffer
        {
            set
            {
                this.byteBuffer = value;
            }
            get
            {
                return this.byteBuffer;
            }
        }
    }
Avatar billede ghorfraq Nybegynder
01. oktober 2003 - 09:10 #14
koden kompilerer. Der laves en exception når jeg prøver at udskrive iClientId fra packet objektet på serversiden efter at have modtaget objektet. På client siden laver jeg et packet objekt om til bytearray og tilbage igen og udskriver for at vise det kan lade sig gøre...
derefter sender jeg til serveren
Avatar billede arne_v Ekspert
01. oktober 2003 - 09:51 #15
Har server adgang til Packet klassen i samme version som Client ?
Avatar billede ghorfraq Nybegynder
01. oktober 2003 - 10:02 #16
accepterede lige dit svar.
Server og client ligger i hver sin mappe med hver sin packetklasse. De er så identiske. MEn måske jeg sku ligge packet i sin egen folder og dermed bruge præcist den samme fil begge steder?
Avatar billede arne_v Ekspert
01. oktober 2003 - 10:32 #17
Måske.

Jeg kunn eogså prøve at køre din kode.

Men det bliver først sidst på eftermiddagen (har kun .NET derhjemme - ikke
på arbejde).
Avatar billede ghorfraq Nybegynder
01. oktober 2003 - 10:37 #18
okay, hvis du finder ud af noget kan du evt maile til bukster90@hotmail.com
hvis jeg løser problemet poster jeg lige herinde
Avatar billede ghorfraq Nybegynder
01. oktober 2003 - 12:19 #19
jeg har nu løst problemet. Jeg delte class Packet sourcefilen mellem klienten og serveren således objektet på henh. server og klient-side bliver oprettet udfra samme sourcefil. Og så virker det. Men takker for din interesse og den hjælp du har givet.
Avatar billede jobless Nybegynder
31. januar 2010 - 17:46 #20
Sidder og bokser med nøjagtigt samme problem...

Selvom jeg kopierer min sourcefil til mit custom object fra det ene projekt til det andet, fungerer det stadigt ikke.

Når du skriver at du har 'delt' filen, hvad mener du så helt præcist ?
Avatar billede ghorfraq Nybegynder
03. februar 2010 - 15:58 #21
Hej Jobless.

Det er godt nok længe siden jeg baksede med det problem :-). Helt tilbage i 2003 så det kniber altså med at huske det.

Hvis jeg husker rigtigt (hvilket aboslut ikke kan garanteres) så havde jeg den samme source-fil (Packet.cs) liggende 2 steder. Dvs. både i min server mappe og en tilsvarende i min client mappe.
Jeg vil tro jeg endte med at oprette en anden mappe (måske: util) og lagde Packet.cs deri og lod client og server refere til den fil.

Men, som sagt. Det ligger adskillige år tilbage og jeg ovenstående projekt er for længst out of sight :-).

Håber denne kommentar kan bruges til noget. Ellers har jeg nok ikke rigtig flere ideer.
Avatar billede jobless Nybegynder
09. februar 2010 - 18:11 #22
Ok, tak for tilbagemeldingen.

Jeg fik det løst ved at bruge en binder, og deri kunne jeg replace assembly og typename, så de stemte overens med applikatiolnen.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester