Single connection server using sockets

I have a problem which is bugging me since I started working with sockets in .Net (in VB6 I would not have this problem. I need to create a Serer that accepts a connection from 1 client only.

This is s sample code for the connection process...

The problem is that as you can see is that even though I have socketListener.Listen(0); , I still can have more than 1 client connected to the server.

I mean:
Client1 connects to the server, he gets "Hello World".
Client2 connects to the server and the connection stays opened for the client (The server doesn't rejects the connection).

If a 3rd client tries to connect to the server then he would get:
"Connecting to 192.168.1.100..."

If I close the connection of Client1 then now Client2 continues with the Accept and also gets "Hello World".


This is not what I want.
I want that Client2 will also get "Connecting to 192.168.1.100..."


I had "solved this problem in the past by doing:
                socketWorker = socketListener.EndAccept(ar);
                IPEndPoint ep = socketWorker.RemoteEndPoint as IPEndPoint;
                RemoteIP = ep.Address.ToString();
                socketListener.Close();

By this way I close the Listener and therefore no other connection is allowed. But then when the Listener needs to return to listen after the client closed the connection, I need to create a new socketListener object and bind it again.
This works, but after lots of connect disconnect and Listen cycles, something get screwed, and I can't get back to Listen.

(I get some exceptions on the Connect, or when I try to Bind the port, I get that the port is already in use).

How can I make yhe code so it will only accept connection from 1 client only and all other connections will be rejected ("Connecting to 192.168.1.100...")?

Thanks.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Diagnostics;

namespace TcpListen
{
    public partial class Form1 : Form
    {
        public event EventHandler OnConnect;
        public event EventHandler OnClose;
        public delegate void DataReceivedDelegate(object sender, byte[] receivedBytes);
        public event DataReceivedDelegate OnDataReceived;
        public delegate void SocektErrorDelegate(object sender, SocketError socketError);
        public event SocektErrorDelegate OnSocektError;


        private Socket socketListener;
        private Socket socketWorker;
        private object objectLocker = new object();
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            socketListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ep = new IPEndPoint(IPAddress.Any, 1234);
            try
            {
                socketListener.Bind(ep);
            }
            catch
            {
                throw;
            }

            socketListener.Listen(0);
            socketListener.BeginAccept(onConnect, null);
        }

        private void onConnect(IAsyncResult ar)
        {
            try
            {
                lock (objectLocker)
                {
                    socketWorker = socketListener.EndAccept(ar);
                    IPEndPoint ep = socketWorker.RemoteEndPoint as IPEndPoint;
                    try
                    {
                        Send(ASCIIEncoding.ASCII.GetBytes("Hello World"));
                    }
                    catch
                    {
                    }
                    waitForData();
                }     
            }
            catch (Exception ex)
            {
            }
        }

        private void waitForData()
        {
            SocketState socketState = new SocketState();
            socketState.Socket = socketWorker;
            socketState.ReceivedData = new byte[1024];
            socketWorker.BeginReceive(socketState.ReceivedData, 0, socketState.ReceivedData.Length, SocketFlags.None, out socketState.ErrorCode, onDataReceived, socketState);
        }

        private void onDataReceived(IAsyncResult ar)
        {
            SocketState socketState = null;
            try
            {
                socketState = (SocketState)ar.AsyncState;
                int cbRead = 0;
                cbRead = socketWorker.EndReceive(ar);
                if (cbRead > 0)
                {
                    if (OnDataReceived != null)
                    {
                        byte[] temp = new byte[cbRead];
                        Array.Copy(socketState.ReceivedData, 0, temp, 0, cbRead);
                        OnDataReceived(this, temp);
                    }
                    waitForData();
                }
                else
                {
                    if (OnClose != null)
                    {
                        OnClose(this, null);
                    }
                    socketListener.BeginAccept(onConnect, null);
                }
            }
            catch (ObjectDisposedException od)
            {

                if (OnClose != null)
                {
                    OnClose(this, null);
                }
                socketListener.BeginAccept(onConnect, null);
            }
            catch (SocketException se)
            {
                if (OnSocektError != null)
                {
                    OnSocektError(this, socketState.ErrorCode);
                }
                socketListener.BeginAccept(onConnect, null);
            }
            catch (Exception ex)
            {
                if (OnSocektError != null)
                {
                    OnSocektError(this, socketState.ErrorCode);
                }
                socketListener.BeginAccept(onConnect, null);
            }
        }

        public void Send(byte[] buffer)
        {
            try
            {
                socketWorker.Send(buffer);
            }
            catch
            {
                throw;
            }
        }

        private class SocketState
        {
            public Socket Socket { get; set; }
            public byte[] ReceivedData { get; set; }
            public SocketError ErrorCode;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (socketWorker != null)
            {
                try
                {
                    socketWorker.Close();
                }
                catch { }
            }
        }
    }
}

Open in new window

LVL 11
saraganiAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

saraganiAuthor Commented:
If the problem is still now understood, I want the backlog to be 0 not 1.
Even though I write 0 on socketListener.Listen(0), it ignores me and still saves a place in the queue for 1 backlog connection.

The code acts the same if I write ether socketListener.Listen(0), or socketListener.Listen(1).

I don't want backlog connections at all. How do I solve that?
0
akhileshcoerCommented:
With Listen(0), i also thought of no backlog should be there (Two clients were able to connect but i found one more intresting thing the 3rd client gets connection refused error)

But still we can workaround that ;-)

There is no need to close the listner, just close the socket after fist connection is established and yuo have accepted.
Now when 2nd client tries to connect...of course it can connect but can't send any data because socket is closed.

Now when you work is done you can either perform other pending requests or just can ignore all of them.

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
saraganiAuthor Commented:
Ok, can you give me a code example, cause I'm a little confused....
I'm not sure which socked I need to close.

Assuming someone (which is the first guy, Client1) tries to connect the server, I will not close his connection.

If not another guy tries to connect the server (Client2) i can't close his socket since it is not an active connection (The connection is half opened. I don't get the Asych Callback of the BeginAccept).

Why I can't do what is possible in VB6??
Is .Net that lame?
0
akhileshcoerCommented:
it is not the .net lame it the way we you are using socket and listener. In VB6 code you are closing the listener which will give "connection refused" kind of errors.
This kind of logic you can implement in .net also. but i think keeping listener active and closing socket should do you job.

you can just call socket.close() to close the socket and check listener.pending() to check if there are any pending request in pipeline. if yes, then its you call what to do with that
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.