VC++ Socketing

Joined
Mar 26, 2006
Messages
603
Reaction score
7
So I've been learning how to use VC++ for fun. I began playing around with sockets.
I can read 1 client, but cannot send information to a second one or check if it exists.
Basically I'm wanting the server to check how many clients are connected and allow them to interact through the server.

Could someone possibly look at what I have and point me in the right direction.
Or if you tell me what I've done wrong explain how you've fixed it.
Thanks in advance.

P.S. If someone also has anything on Connecting to MySQL could you give me a good link to read?

Code:
Code:
	public: void server() {
		IPAddress^ localAddr = IPAddress::Parse( "127.0.0.1");
                Int32 port = 13000;
		IPEndPoint^ ep = gcnew IPEndPoint( localAddr,port );

		ipendpoints = gcnew array<IPEndPoint^>(1);
		ipendpoints[0] = ep;

		Socket^ server = gcnew Socket( AddressFamily::InterNetwork,SocketType::Stream,ProtocolType::Tcp );
		srv = gcnew array<Socket^>(1);
		srv[0] = server;
		
		con = gcnew array<Socket^>(2);
		array<Byte>^bytes = gcnew array<Byte>(256);
		array<Byte>^buffer = gcnew array<Byte>(1024);

		String^ data = nullptr;
		String^ recieved;

		srv[0]->Bind( ipendpoints[0] );

		srv[0]->Listen(15);

		String^ output;
		data = nullptr;
		Int32 i;
		while(true) {
                        if(Socket^ client = srv[0]->Accept()) {
			     con[cn] = client;
                             cn++;
                        }
			}
	}
 
Last edited:
You're using arrays wrong. You're going to overrun con after a third client is accepted. bytes and buffer are are never used, but if you intend to receive any data into either array, you need to synchronize access to the objects across sockets. I'm also not sure what the point of initializing a server socket and placing it in a single-celled array is either. You also assigned nullptr to data twice, which is probably a poor idea if you intend on reading that string at any point asynchronously, which you will if you're using sockets properly.
 
You're using arrays wrong. You're going to overrun con after a third client is accepted. bytes and buffer are are never used, but if you intend to receive any data into either array, you need to synchronize access to the objects across sockets. I'm also not sure what the point of initializing a server socket and placing it in a single-celled array is either. You also assigned nullptr to data twice, which is probably a poor idea if you intend on reading that string at any point asynchronously, which you will if you're using sockets properly.

Originally I had seperate functions for each one. I assigned it to an array to pass it to the socket function. Could you elaborate on how I'm using the array wrong so I could read more into it. I know my array is assigned for only 2 client connections which is what I want at the moment to make sure I can connect multiple clients.
 
Originally I had seperate functions for each one. I assigned it to an array to pass it to the socket function. Could you elaborate on how I'm using the array wrong so I could read more into it. I know my array is assigned for only 2 client connections which is what I want at the moment to make sure I can connect multiple clients.

The moment a third connection is made, your array is overrun and the application crashes. That's not desirable behavior. What you should be doing is using an IList containing your socket sessions.

Instead of

PHP:
while(true) {
    if(Socket^ client = srv[0]->Accept()) {
        con[cn] = client;
        cn++;
    }
}

Try

PHP:
class TcpServer
    {
        bool m_listening;
        TcpListener m_server;
        Task m_listener;

        public TcpServer(string ipAddress, int port)
        {
            m_server = new TcpListener(IPAddress.Parse(ipAddress), port);
        }
        public Task Listen(Action<Socket> callback)
        {
            m_listening = true;
            m_server.Start();

            if (m_listener == null) {
                m_listener = Task.Factory.StartNew(async () => {
                    while (m_listening) {
                        callback(await m_server.AcceptSocketAsync());
                    }
                });
            }
            return m_listener;
        }
        public void Stop()
        {
            m_listening = false;
            m_server.Stop();
        }
    }

Additionally, you could add a CancellationTokenSource to the class to ensure that the task ends before another can begin, but this code will work fine save for that infinitesimally improbable race condition, which wouldn't really affect your program in any meaningful way. TcpServer can then be used as follows:

PHP:
            int capacity = 2;

            List<Socket> clients = new List<Socket>();
            TcpServer server = new TcpServer("127.0.0.1", 13000);

            server.Listen((c) => {
                if (clients.Count > capacity) {
                    // Notify c and terminate the socket
                } else {
                    clients.Add(c);
                    // Communicate here
                }
            })
            // When Listen() completes, execute the following
            .ContinueWith((t) => {
                Console.WriteLine("Server stopped.");
            });
 
You can also use threads for this.

[c/c++] How To Code A Multi-client Server In C\++ Using Threads - rohitab.com - Forums

Try that out :) could be good to learn about threads as well!

EDIT: I didn't read your code admittedly, but I assume that if you try to recv data with your code it's gonna block the rest of the sockets until that socket gets it's data? :) (I know I ran into that problem myself before).
That's where you are gonna need either threads or asynchonous socketing.
 
The moment a third connection is made, your array is overrun and the application crashes. That's not desirable behavior. What you should be doing is using an IList containing your socket sessions.

Instead of

PHP:
while(true) {
    if(Socket^ client = srv[0]->Accept()) {
        con[cn] = client;
        cn++;
    }
}

Try

PHP:
class TcpServer
    {
        bool m_listening;
        TcpListener m_server;
        Task m_listener;

        public TcpServer(string ipAddress, int port)
        {
            m_server = new TcpListener(IPAddress.Parse(ipAddress), port);
        }
        public Task Listen(Action<Socket> callback)
        {
            m_listening = true;
            m_server.Start();

            if (m_listener == null) {
                m_listener = Task.Factory.StartNew(async () => {
                    while (m_listening) {
                        callback(await m_server.AcceptSocketAsync());
                    }
                });
            }
            return m_listener;
        }
        public void Stop()
        {
            m_listening = false;
            m_server.Stop();
        }
    }

Additionally, you could add a CancellationTokenSource to the class to ensure that the task ends before another can begin, but this code will work fine save for that infinitesimally improbable race condition, which wouldn't really affect your program in any meaningful way. TcpServer can then be used as follows:

PHP:
            int capacity = 2;

            List<Socket> clients = new List<Socket>();
            TcpServer server = new TcpServer("127.0.0.1", 13000);

            server.Listen((c) => {
                if (clients.Count > capacity) {
                    // Notify c and terminate the socket
                } else {
                    clients.Add(c);
                    // Communicate here
                }
            })
            // When Listen() completes, execute the following
            .ContinueWith((t) => {
                Console.WriteLine("Server stopped.");
            });

Thank you. I haven't tested this, but I will test when I get back home. I haven't messed with Classes much nor arrays. Kind of jumping from PHP to .Net. I've been doing PHP for a couple of years so I understand the concepts to some of .Net but not much as everything is used different. Where I'm use to
Code:
 $this[element]= "blah",
, you have to do
Code:
array<String^>^this = gcnew array<String^>; this[0]="Blah"
I'll try this and give some feedback if I have any other problems, Thanks.
 
why are you using .net c++?

The syntax is similar to Brainfuck, and it's almost as powerful as Visual Basic. Why not use C++/CLI? :zippy:

@lordvladek

Converting my code to C++/CLI shouldn't be too difficult a task, but you'll need Visual Studio 11 to compile it. The line
PHP:
if (clients.Count > capacity) {
should be
PHP:
if (clients.Count >= capacity) {
as well.
 
why are you using .net c++?

I chose .net to begin learning c++, although the syntax is different. You can still use regular c++. You can also do everything I would like to do without having to study how to code a GUI for use. I'm not big on working within the console and I'm just making small programs for my own use and as I'm progressing I'm learning both how to write it in regular c++ as well as in managed c++. Its also easier for me myself to learn at a faster rate while I'm in college (I'm a full time student for Information Security and Cybersecurity). So I guess my main reasoning being so I can write my own tools for things such as packet decyption, MITM attacks, Bruteforcing, etc. I use pre-written programs but, if I write my own its not as easy to prevent something you know nothing about. But in any case at the same time I'm wanting to expand my knowledge. So I'm pretty much reading everything I find on Managed C++ and conversion between managed -> Regular. Although I do agree managed isn't the way to go, Its not as much of a headache for me to sit here and learn.

@AngraMainyu I'll work on converting it. I'm still nowhere near proficient but I'll figure it out. I mainly couldn't figure out why it wouldn't store multiple connections. And there isn't very much information in the documentation on async connections, and winsock connections confuse me insanely bad. I do have one more question. Say I have a fixed image in a picture box, And instead of the top left corner showing I would like to say click a button and the position would move to the center of the image. I can't seem to find any documentation on moving by pixels other then completely moving the picturebox location, which in my personal opinion would be useless. But in any case. Thank you for the responses.
 
You can also use threads for this.

[c/c++] How To Code A Multi-client Server In C\++ Using Threads - rohitab.com - Forums

Try that out :) could be good to learn about threads as well!

EDIT: I didn't read your code admittedly, but I assume that if you try to recv data with your code it's gonna block the rest of the sockets until that socket gets it's data? :) (I know I ran into that problem myself before).
That's where you are gonna need either threads or asynchonous socketing.
I'll read it. Yea I'm wanting to receive multiple connections and allow them to interact.
 
Back