Click here to Skip to main content
15,887,596 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello!
I need to make a TCP client that will send message to server from certain port (for example 50000). I've tried to call Bind method before Send, and it works, but only for the first time. Message is sent from the port that i've chosen before, but when i'm trying to call it a second or more time, the exception comes: "usually allow to use only one address". When i'm restarting my form it's repeating once again: first - ok, then - exception. I read, that such exception comes, because port from which i sending message has no time for free itself, and it's required more time. Here is the code of my client:

private void button2_Click_1(object sender, EventArgs e)
{
    string local_host = System.Net.Dns.GetHostName();
    string local_ip_address = Dns.GetHostByName(local_host).AddressList[0].ToString();
    IPEndPoint send_point = new IPEndPoint(IPAddress.Parse(local_ip_address), 50000);

    Socket send_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    IPEndPoint connected_point = new IPEndPoint(IPAddress.Parse(textBoxIPListen.Text), 
                                                Convert.ToInt32(textBoxPortListen.Text));
    try
    {
        send_socket.Bind(send_point);
        send_socket.Connect(connected_point);
        byte[] data = Encoding.Unicode.GetBytes("TestTest");
        send_socket.Send(data);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
    finally
    {
        send_socket.Close();
        ((IDisposable)send_socket).Dispose();
    }
}


What I have tried:

I had recommendation to close socket with Close() method, use in the end Dispose(), Shutdown(), Disconnect() and send_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true) but unfortunately nothing works. Is it ever possible to bind client socket everytime before send it ? If so, what should i do, can you please help?
Posted
Updated 19-Jan-17 23:00pm

1 solution

The simple solution:
Don't bind the client socket to a specific port. There is usually no need to do so.

The problem you are seeing is sourced by the socket not being closed internally when calling the Close method and the connection has not been shut down gracefully as explained in the SO thread c - When binding a client TCP socket to a specific local port with Winsock, SO_REUSEADDR does not have any effect - Stack Overflow[^]:
Quote:
The error you mentioned normally happens when the last connection to the same host:port didn't have a graceful shutdown (FIN/ACK FIN/ACK). In these cases, the socket stays in TIME_WAIT state for a certain period of time (OS dependent, but adjustable).
The thread contains also possible solutions. So you might try to set the Socket.LingerState Property (System.Net.Sockets)[^].
 
Share this answer
 
Comments
nie_trzeba 20-Jan-17 5:41am    
I would love to not binded client to specific port, but my boss wanted that message always sended from one specific port :/
I read and tried to configure sockets option with Socket.LingerState() as you advise me, and put it anywhere in my code, but unfortunatelly it's doesn't helping. I set Socket.LingerState.LingerTime = 0, but anyway it didn't help me. Seriously, i don't know what else to do with it.
Jochen Arndt 20-Jan-17 6:04am    
Sorry that it did not work. It should be set just after creating the socket (using true and timeout zero).

Another solution might be using the hammer:
Terminate the usage of winsocks using the WSACleanup() API call using PInvoke. That might release the socket but would be an ugly solution.

You may also ask your boss why it should be a fixed port. I guess that he can't give you a reasonable answer. But he's the boss.
nie_trzeba 20-Jan-17 7:10am    
Really weird, cause so many things that help others didn't help at my case. Maybe just my arms grow from the wrong side ? :)

I never heard about that, so i googled about it, and tried to make just like at that link https://www.experts-exchange.com/questions/21014265/PInvoke-winsock-WSAStartup-and-WSACleanup-in-c.html , but unfortunatelly it's didn't help too.

I asked my boss why he want it, and his answer was quite reasonable. The point is that we are making a server, that we will sell later to companies, and he afraid, that at some PC's firewall may be blocked some ports, and system couldn't choose the right one without bind, and message couldn't be send. I really bad at firewalls or etc so it was sounds true for me.

Anyway, thanks very much for your trying and wasted time on me, it's really cool :)
Jochen Arndt 20-Jan-17 7:35am    
I expected such a "reason".

That's not how normal TCP works. A server has to use a fixed port number on which he is listening on. It must be fixed because the client has to know it. But there is no reason to use a fixed port number on the client.

Firewalls use "stateful inspection". That means that they track the port numbers (and other information) of outgoing initial packets. If there are packets coming in to a port that is tracked (belongs to the communication that was initiated before), they are allowed to pass.

So only the port used by the server must be allowed in the firewall input settings of the server. The firewall settings on the client does not care with respect to the ports of established connection.

They may be off course configured to be more restrictive. But it is not your problem if someone misconfigures his firewall in such a way. When he is not able to connect to your server, he will be probably also not able to use a web browser or a mail client.
nie_trzeba 20-Jan-17 7:47am    
Thank you very much for your answer! I will try to describe and prove this to my boss. Thank you for your help !

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900