Socket/Threading Question

07/31/2011 23:03 xBlackPlagu3x#1
Alright so I've been following InfamousNoone's C# for idiots tutorial (video set) and I've just finished watching them all. I can now say I'm very very interested in sockets and whatnot. So the problem is, I'm trying to use sockets to creating a mini Messaging client and I've gotten to the point where I can send a message back in forth. But this is how it works.

The ONLY way you can send a message is if you receive one first. That's obviously a problem! I've tried to start multiple threads but I just don't know how. (I just got out of a threading lesson but 5 days ago) No matter how I do it, I can't figure out a way to be able to send messages over and over without having a block. Can anyone tell me how I'd be able to do this?


Here's the entire code:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.NativeInterop;
using System.Net.Sockets;
using System.Threading;

namespace MeteoraMSGClient
{
    class Program
    {
        public static string MSG;
        private static void MSGSendThread(WinsockClient Sender, object Arg)
        {
            MSG = Console.ReadLine();
            Sender.Send(Encoding.ASCII.GetBytes(MSG));
        }
        static void Main(string[] args)
        {

            WinsockClient Client = new WinsockClient(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            Client.OnConnect += new SocketEventCallback<WinsockClient, object>(Client_OnConnect);
            Client.OnDisconnect += new SocketEventCallback<WinsockClient, object>(Client_OnDisconnect);
            Client.OnReceive += new SocketEventCallback<WinsockClient, byte[]>(Client_OnReceive);

            byte[] ClientRecvBuffer = new byte[255];
            Client.Enable("**********", 9958, ClientRecvBuffer);
                
        }
        static void Client_OnReceive(WinsockClient Sender, byte[] Arg)
        {
            Console.WriteLine("New message!");
            Console.WriteLine("\t >> " + Encoding.ASCII.GetString(Arg));
            MSG = Console.ReadLine();
            Sender.Send(Encoding.ASCII.GetBytes(MSG));
        }

        static void Client_OnDisconnect(WinsockClient Sender, object Arg)
        {
            Console.WriteLine("We have disconnected from the server");
        }

        static void Client_OnConnect(WinsockClient Sender, object Arg)
        {
            Console.WriteLine("We have connected to a server");
            MSG = Console.ReadLine();
            Sender.Send(Encoding.ASCII.GetBytes(MSG));
        }
    }
}
07/31/2011 23:06 pro4never#2
You need to keep an instance of the WinsockClient so you can use its .Send method.

This could be done via a dictionary, a single 'user' or however you want.

When someone connects you save that connection and then use it to .Send.

Example.

WinsockClient user;

in the on connect you say

user = Sender;

then whenever you want to send something just do user.Send(byte array);
07/31/2011 23:10 xBlackPlagu3x#3
Quote:
Originally Posted by pro4never View Post
You need to keep an instance of the WinsockClient so you can use its .Send method.

This could be done via a dictionary, a single 'user' or however you want.

When someone connects you save that connection and then use it to .Send.

Example.

WinsockClient user;

in the on connect you say

user = Sender;

then whenever you want to send something just do user.Send(byte array);
(First off, I don't know if you've just become one but I've never noticed it before so congratulations on becoming a mod)

This sounds exactly what I'd be needing to use but could you either reword it or add a little bit more to your example? I've never used a dictionary entry or hashtable, etc.

Also, basically what you're saying is that I could handle the messaging in the OnConnect?
07/31/2011 23:17 pro4never#4
Yes, you'd handle it during OnConnect.

a Dictionary lets you hold a key and value as a pair. This means that you could (for example) do something like...


Dictionary<WinsockClient, Player> Clients = new Dictionary<WinsockClient, Player>();


Then during the OnConnect you'd say...

if(!Clients.ContainsKey(Sender))
Clients.Add(Sender, new Player(Sender));

On Disconnect you'd say...

if(Clients.ContainsKey(Sender))
Clients.Remove(Sender);

On receive you'd say...

if(!Clients.ContainsKey(Sender))
//Throw error

else you know which Player has sent you a packet and you can process the packet for that user.


There are many ways of doing it many of which have no uses for dictionaries, this is just a simple example.