Skip to main content
gamedev.net
🔒 Locked 🎮 Unity

C#, shared assemblies, and serialization

Started by tikiwasabi Jan 13, 2007 at 1:46 AM 4 replies 1.4k views
Original Post
tikiwasabi
tikiwasabi
Hello, I've started working on serialization and deserialization coupled with networking and am having trouble. In order to accomplish what I'm trying to do, I was told I would have to share an assembly file among my two projects in order to cast one 'player' object to another when it arrives at the server/client. Client


class Program
{
    static void Main(string[] args)
    {
        Process();
    }

    static void Process()
    {
        Stream stream;
        TcpClient tcpClient = new TcpClient();
        MemoryStream memoryStream;
        BinaryFormatter binaryFormatter;
        const string IP = @"127.0.0.1";
        const int PORT = 5055;
        IPAddress ipAddress = IPAddress.Parse(IP);
        Player player = new Player();

        try {

            tcpClient.Connect(ipAddress, PORT);

            while (true) {

                using (stream = tcpClient.GetStream()) {

                    using (memoryStream = new MemoryStream()) {

                        Console.Write("Send to server? (y/n) > ");
                        string input = Console.ReadLine().ToUpper();
                        if (input[0] == 'Y') {
                            binaryFormatter = new BinaryFormatter();
                            binaryFormatter.Serialize(memoryStream, player);
                            byte[] buffer = memoryStream.GetBuffer();
                            stream.Write(buffer, 0, buffer.Length);
                        }
                        memoryStream.Close();
                    }
                    stream.Close();
                }
            }
        } catch (Exception e) {
            Console.WriteLine(e.Message);
            Console.ReadLine();
        }
    }
}

[Serializable()]
class Player : ISerializable
{
    private string name;
    private int level;

    public Player()
    {
        this.name = "Default";
        this.level = 1;
    }

    public Player(SerializationInfo info, StreamingContext context)
    {
        this.name = (string)info.GetValue("Name", typeof(string));
        this.level = (int)info.GetValue("Level", typeof(int));
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Name", name);
        info.AddValue("Level", level);
    }
}



Server


using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using System.Runtime.CompilerServices;


class Program
{
    static void Main(string[] args)
    {
        Serve();
    }

    public static void Serve()
    {
        Player player = new Player();
        Socket socket;
        TcpListener tcpListener;
        Stream stream;
        MemoryStream memoryStream;
        BinaryFormatter binaryFormatter;
        const int PORT = 5055;
        tcpListener = new TcpListener(IPAddress.Any, PORT);

        tcpListener.Start();

        Console.WriteLine("Server started on port {0}", PORT);
        Console.WriteLine("Waiting for connections");

        while (true) {
            socket = tcpListener.AcceptSocket();
            Console.WriteLine("[{0}] has connected", socket.RemoteEndPoint);

            try {
                using (stream = new NetworkStream(socket)) {

                    using (memoryStream = new MemoryStream()) {
                        binaryFormatter = new BinaryFormatter();
                        byte[] buffer = new byte[512];
                        int bytesReceived;

                        while ((bytesReceived = stream.Read(buffer, 0, 512)) != 0) {

                            memoryStream.Write(buffer, 0, 512);
                        }

                        memoryStream.Seek(0, 0);
                        player = (Player)binaryFormatter.Deserialize(memoryStream);

                        memoryStream.Close();
                    }
                    stream.Close();
                }
            } catch (Exception e) {
                Console.WriteLine(e.Message);
                Console.ReadLine();
            }
        }
    }
}

[Serializable()]
class Player : ISerializable
{
    private string name;
    private int level;

    public Player()
    {
        this.name = "Default";
        this.level = 1;
    }

    public Player(SerializationInfo info, StreamingContext context)
    {
        this.name = (string)info.GetValue("Name", typeof(string));
        this.level = (int)info.GetValue("Level", typeof(int));
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Name", name);
        info.AddValue("Level", level);
    }
}



It compiles just fine, but when the server attempts to cast the remote player object to a local player object, I receive the error <Unable to cast object of type 'Player' to type 'Player'. So far I've: 1) Created a strong name 2) Added the .exe from the client directory to the GAC 3) Profit? No. I'm probably forgetting something or doing something wrong (probably two) Any ideas?
Washu
Washu
Quote:
Original post by tikiwasabi
Hello,

I've started working on serialization and deserialization coupled with networking and am having trouble. In order to accomplish what I'm trying to do, I was told I would have to share an assembly file among my two projects in order to cast one 'player' object to another when it arrives at the server/client.

Client

*** Source Snippet Removed ***

Server

*** Source Snippet Removed ***

It compiles just fine, but when the server attempts to cast the remote player object to a local player object, I receive the error
So far I've:

1) Created a strong name
2) Added the .exe from the client directory to the GAC
3) Profit? No. I'm probably forgetting something or doing something wrong (probably two)

Any ideas?


No, what I told you was: You need to make an assembly that contains all of the shared objects. Now, your source code does not indicate that you have done such. Sharing an assembly between the two is not enough. The assembly must contain all shared resources.
In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
tikiwasabi
tikiwasabi
Doh. I'll try again. :p
alunharford
alunharford
Create one project containing the server code (without 'Player' etc).
Create another project containing the client code (without 'Player' etc).
Create another project containing the shared code (such as 'Player').

Now add a reference from the server code to the shared code, and from the client code to the shared code.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.