I'm working on a game version of Game of the Generals (board game). Basically, it plays like checkers, but I wanted to add multiplayer functionality, with an additional chat function. A player starts a server, another player on another PC (in the same network) starts a client, client connects to server, then they send data to each other (supposedly a 2D array containing pieces).

I've been researching on TCP Sockets and threads and stuff, but none are noob friendly and all of them use some pretty technical words and functions I've never seen before, which, I'd like to assume, means my early work on the program will be scrapped.

So, basically, I'd like to ask, what is the easiest approach to this? A friend told me multi-threaded sockets would do the trick, while another said something about asynchronous or something. Still, another suggested .NET remoting stuff.

How would you do this? A permanent loop?

So far, here's what I have:

For the server, the following code is loaded on Form Load. The program can never load the form, though. I'm assuming it has something to do with the while loop.

TcpListener serverSocket = new TcpListener(IPAddress.Any, 8888);
            int requestCount = 0;
            TcpClient clientSocket = default(TcpClient);
            serverSocket.Start(2);
            clientSocket = serverSocket.AcceptTcpClient();
            requestCount = 0;

            while ((true))
            {
                try
                {
                    requestCount = requestCount + 1;
                    NetworkStream networkStream = clientSocket.GetStream();
                    byte[] bytesFrom = new byte[10025];
                    networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
                    string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
                    dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
                    lblStatusBar.Text = " >> Data from client - " + dataFromClient;
                    string serverResponse = "Server response " + Convert.ToString(requestCount);
                    Byte[] sendBytes = Encoding.ASCII.GetBytes(serverResponse);
                    networkStream.Write(sendBytes, 0, sendBytes.Length);
                    networkStream.Flush();
                    Console.WriteLine(" >> " + serverResponse);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }

            clientSocket.Close();
            serverSocket.Stop();

And this is for the Client:

clientSocket.Connect(txtIPAd.Text, 8888);

            NetworkStream serverStream = clientSocket.GetStream();
            byte[] outStream = System.Text.Encoding.ASCII.GetBytes("Message from Client$");
            serverStream.Write(outStream, 0, outStream.Length);
            serverStream.Flush();

            byte[] inStream = new byte[10025];
            serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
            string returndata = System.Text.Encoding.ASCII.GetString(inStream);
            lblStatusBar.Text = returndata;

Again, pretty basic stuff. If I use the same PC as a client and a server, the client responds. When I put the client on a different PC, the client returns a "No connection could be made because the target machine actively refused it."

My Server machine is Windows 7, and my Client Machine is Windows Vista. Both programs are allowed through the firewall, and both are running as administrator.

Dani AI

Generated

Short version: the form never finishes loading because the listener/accept/read loop is running on the UI thread, and the remote "actively refused" error usually means the server either isn’t listening on the address/port the client used or a firewall/router is blocking the connection. Fix the UI freeze first, then make the network I/O robust (check bytes read, use proper framing), and only then troubleshoot connectivity.

Minimal, compatible pattern (run the listener off the UI thread, check bytesRead, update the UI safely):

TcpListener listener = new TcpListener(IPAddress.Any, 8888);
listener.Start();
ThreadPool.QueueUserWorkItem(delegate {
    while (true) {
        TcpClient client = listener.AcceptTcpClient();
        NetworkStream stream = client.GetStream();
        byte[] buf = new byte[1024];
        int bytesRead;
        while ((bytesRead = stream.Read(buf, 0, buf.Length)) > 0) {
            string msg = Encoding.ASCII.GetString(buf, 0, bytesRead);
            this.BeginInvoke((MethodInvoker)delegate { lblStatusBar.Text = msg; });
        }
        client.Close();
    }
});

Debug checklist for the "actively refused" problem:

  • Confirm the server process is running and listening: run netstat -an | find ":8888" on the server to see LISTENING.
  • Make sure the client uses the server’s LAN IP (e.g. 192.168.x.y), not 127.0.0.1.
  • Temporarily disable the Windows Firewall (or add an inbound rule for the EXE/port) to rule out firewall blocks.
  • Try telnet serverIP 8888 from the client to test reachability.
  • If both machines are on different subnets or there’s a router, check NAT/port-forwarding.

Notes and next steps: use a length-prefixed message or an agreed delimiter but always respect the number of bytes returned by Read; do not assume a single Read equals a complete message. For a long-term, higher-level approach follow ’s advice to use WCF (preferred over remoting) — or, for very quick prototyping, ’s shared-folder trick works but is fragile.

Recommended Answers

All 4 Replies

friend told me multi-threaded sockets would do the trick

They will but dealing with a raw socket is a steep learning curve. For this application I would not recommend it.

while another said something about asynchronous or something.

Asynchronous sockets, remoting, etc. Its just a non-blocking way of programming.

Still, another suggested .NET remoting stuff

Remoting has been deprecated in favor of WCF. I would use WCF.

How would you do this? A permanent loop?

No. Use callbacks or asynchronous method.

I would recommend using WCF. With WCF it basically bridges the network-level gap. You can have two computers running the application and you can call C# methods on computer #2 from computer #1. You don't have to worry about assembling and parsing socket data you simply call IOtherPlay.YourTurn() .

This is where I started learning WCF:

You'll have to be careful not get mixed up between WPF & WCF. WPF is basically used instead of WinForms but the application implements WCF for chatting. Take a look at how its done. The config files are a real pain to initially get set up but after you have your basic framework down you can add new methods and types in minutes.

Somewhat advanced topics but you could probably use them down the road:
http://ayende.com/Blog/archive/2008/03/29/WCF-Async-without-proxies.aspx

The EASIEST method would be to share a folder on both machines where files can be saved (ie full access). This would work best with only 2 players. Example:

\\COMPUTER1\GameData\data.txt

Have some sort of timer checking this folder for data on Computer1. If it has a file, load its contents into the game then delete the file. Same goes for Computer2 (\\COMPUTER2\GameData\data.txt).

This is about the easiest method I can think of. You might learn a bit from it in terms of timing things and might develop a bit of respect for asynchronous methods of communication. Once you have this working, you may wish to look into blocking sockets, then finally asynchronous sockets. The reason why I sugguest learning in this order is because:

1)First method - utilizes simple windows file sharing/file systems that you are (or should be) pretty comfortable with already. This will help you learn the basics of how intercommunication works.
2)Blocking sockets - this will give you a pretty good idea of how sockets work. It will be blocking (a fancy way of saying it will cause your application to hang during send/recieve operations) but for a board game with maybe 1 packet sent every 20 seconds this should be no problem.
3)Async sockets - this opens a whole new realm of programming, most of which you won't be at all comfortable with. (Which is why you should learn it last). This includes at least a basic understanding of delegates, threads, the IAsyncResult interface, serialization/deserialization, binary formating, callback funcs, timing issues, memorystreams and probably some stuff I can't think of right now. (Some of this stuff might be required to get blocking sockets to work as well.)

Good luck! If you need any help along the way, feel free to ask. I get bored at work quite a bit.

commented: i hope you're not a software developer -3

Thanks for the reply, guys.

Remoting has been deprecated in favor of WCF. I would use WCF.

Unfortunately, I think that requires .NET 3.5 or something. My target machines are running pre-SP3 Windows XP's (yes, outdated, I know).

Is .NET Remoting a good option? As of now, I'm toying around with it, and the way I understand is that basically, the server and client uses data from some sort of class that both machines have access to. Am i right on this, or did I miss something?

Also trying my hand at Asynchronous sockets, since from what I understand, using Socket programming will keep blocking my game.

Thanks in advance.

Is Asynchronous socket programming really THAT complex? I'm currently looking for sample programs, Windows Applications that use asynchronous sockets. I figured it *shouldn't* be too difficult to toss around a few ints and strings.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.