I have an application that needs to stream data up to a server over a particular port. When the application starts it performs a number of checks, for network connectivity, a reachable host, among others. I'd like it to also check the port to ensure it's able to receive data.
I have this code:
Private Function CheckPort(ByVal Host As String) As Boolean
Dim IPs() As IPAddress = Dns.GetHostAddresses(Host)
Dim s As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
s.Connect(IPs(0), <port # removed>)
If s.Poll(-1, SelectMode.SelectWrite) Then
Return True
End If
Return False
End Function
The code works well, but I'm concerned that by performing the check I might be inadvertently preventing subsequent messages from the application from reaching the port. Will performing this check interfere with the actual data I want to send to the host? Should I close the socket with s.close() before returning the function?
I mainly agree with CodeCaster's response.
If you say the server is buggy, it is also probable that a few minutes after you check the port connection, the connection is broken or even closed by the server.
If you still want to do it as a means to reduce risk of making the user write some message that later cannot be sent, this would be a good approach to follow. An alternative is that you can save the data as draft locally or somewhere else for sending it later when the server is available.
Now, going to your code:
You are opening a connection inside function CheckPort so when the function finishes you will lose any reference to s, the open socket. In C, you would have a leak of resources; in Java, a garbage collector will take care of the Socket and close it. I don't know how it is in VB but I'd close that socket before leaving the function. In any case it's a healthy practice.
Additionally, when you have data ready to send you won't be able to do it on the same connection if you lose the reference (s) to the open socket or you close the socket (unless VB has any trick that I don't know). You will have to open a new connection to send data. Don't worry, you will be able to do it even if you made the check before. The server will see it as just a different connection, maybe from a different source port (or could be the same if you closed the connection before, that depends on the OS).
Checking a port before connecting to it is as useful as verifying file existence before opening it: not at all.
The file can be deleted in between checking and opening, and your socket can be closed for a variety of reasons.
Just connect and write to it, it'll throw an appropriate exception when it won't work.
Related
I'm using "redis-rs" for rust and I tested sending a few thousand requests locally
and it works really well at the few first, except that at some point it stops accepting requests
and starts showing me this error when I send a command to redis:
"Only one usage of each socket address (protocol/network address/port) is normally permitted"
I am opening a client and a connection on every request to the http server that takes them in,
that's probably a bad idea in the first place, but shouldn't the connections stop existing and close after the function that opened it ends?
Is there any better solution, like some kind of global connection?
thanks
Well if it is an http server, the crate you are using likely is doing multithreading to handle requests. It is possible that one thread got caught in the process of closing the connection just as another thread began processing the next request.
Or in your case, maybe the remote database has not finished closing the previous request by the time the next connection is created. Either way, it's easier to think of it as a race condition between threads.
Since you don't know what thread will request a connection next, it may be better to store the connection as a global resource. Since I assume a mutex lock is faster than opening and closing a socket, I used lazy_static to create a single thread safe connection.
use lazy_static::lazy_static;
use parking_lot::Mutex;
use std::sync::Arc;
lazy_static! {
pub static ref LOCAL_DB: Arc<Mutex<Connection>> = {
let connection = Connection::open("local.sqlite").expect("Unable to open local DB");
connection.execute_batch(CREATE_TABLE).unwrap();
Arc::new(Mutex::new(connection))
};
}
// I can then just use it anywhere in functions without any complications.
let lock = LOCAL_DB.lock();
lock.execute_batch("begin").unwrap();
// etc.
I don't quite understand exactly how a few of the features are shared when a TcpListener and TcpClient communicate.
Let's say the following code is run (for now ignore synchronisation):
Server:
Dim server As New TcpListener(localAddr, port)
server.Start()
Dim client As TcpClient = server.AcceptTcpClient()
Client:
Dim client As New TcpClient
client.Connect(hostAddr, port)
And the connection is successfully established. Now there are two TcpClient instances — one on server side and one on client side. However, they share the same network stream through TcpClient.GetStream().
I'm slightly confused — does the client pass itself and all of its properties to the server when server.AcceptTcpClient() is called?
What about any changes to either of the TcpClient instances after this? When the connection shuts down I call this on both sides:
client.GetStream.Close()
client.Close()
But I get an exception with TcpClient.GetStream.Close() on the client which executes this code the latest because it tells me that the client is already closed (this happens when the above code isn't perfectly synchronised on both sides).
What about the .SendBufferSize and .ReceiveBufferSize properties? Do I need to set this on both sides of the connection?
Hope someone can clear up my confusion with an explanation of how exactly the TcpClient/Listener classes work during the communication — so far I haven't been able to find documentation explaining what exactly happens.
The TCP protocol does not know what a TcpClient is. This is a .NET concept. TCP does not reference .NET concepts at all. For that reason no objects will be sent across the wire.
The only thing that is sent is the bytes you explicitly write.
Each side has it's own isolated objects. Both sides use their own TcpClient object which acts like a handle to the TCP connection.
client.GetStream.Close()
client.Close()
This is not the proper shutdown sequence. The first line is redundant to the second and incomplete. Close should never be called. The best way to do it is to wrap the client in using. The second best way is to call Dispose on the client. The Close methods in the BCL are historic accidents and should be ignored. They do the same thing that Dispose does in all cases that I ever looked at.
Don't touch the buffer sizes. They control how much memory the kernel uses to buffer data on your end of the connection. The kernel is capable of managing this by itself.
Also don't look at the buffer sizes in your code. They are meaningless. Also don't use the DataAvailable property because if it returns false/0 this does not mean that no data can be read.
The Connected property is not necessarily synchronized on both sides. If the network goes down there can be no synchronization. Never look at the Connected property. If it says true the next nanosecond it could be false. So it's not possible to make decisions based on that property. You do not need to test anything. Just Read/Write and handle the exceptions by aborting.
Regarding packets, you are not sending packets when you Write. TCP has a boundaryless stream of bytes. The kernel packetizes your data internally. You do not need to split data into specific sizes. Just use a fairly big buffer size such as 8K (or more on fast networks). The write size is only about saving CPU time by being less chatty (assuming nagling is enabled).
Do you know if it's possible actually to disconnect a rtmpconnection and how ?
There is no "disconnect" method in the official doc, and also in the rtmpconnection.lzx . So if you know a way out to disconnect the rtmp connection,please let me know. Thanks in advance.
The <rtmpconnection> class in OpenLaszlo uses the ActionScript 3 NetConnection class to connect to the server. The NetConnection class has a method close(), here is the documentation for that:
Closes the connection that was opened locally or to the server and
dispatches a netStatus event with a code property of
NetConnection.Connect.Closed.
This method disconnects all NetStream objects running over the
connection. Any queued data that has not been sent is discarded. (To
terminate local or server streams without closing the connection, use
NetStream.close().) If you close the connection and then want to
create a new one, you must create a new NetConnection object and call
the connect() method again.
The close() method also disconnects all remote shared objects running
over this connection. However, you don't need to recreate the shared
object to reconnect. Instead, you can just call SharedObject.connect()
to reestablish the connection to the shared object. Also, any data in
the shared object that was queued when you issued
NetConnection.close() is sent after you reestablish a connection to
the shared object.
With Flash Media Server, the best development practice is to call
close() when the client no longer needs the connection to the server.
Calling close() is the fastest way to clean up unused connections. You
can configure the server to close idle connections automatically as a
back-up measure.
In the LZX source code for the <rtmpconnection> I can see that NetConnection.close() is only called in case of a connection failure:
<!--- Handle connection failure, attempt to reconnect using altsrc
#keywords private -->
<method name="_handleConnectionFailure" args="msg"><![CDATA[
this._nc.close();
if (this.debug) {
if ($debug) Debug.warn("error connecting to", this._connecturl, ":", msg);
}
....
I don't know why there is no close method defined on the <rtmpconnection> class, but you could add that code for your yourself, by extending the <rtmpconnection> and adding a close method. Just make sure you handle the state variables correctly.
As I haven't used Red5 in a long time, I cannot tell you if Red5 automatically closes NetConnections which are idle.
I'm building a program that has a very basic premise.
For X amount of Objects
Open Conection
Perform Actions
Close Connection
Open Next
Each of these connections is made on a socks5 proxy and after about the 200th connection I get "The operation has timeout" errors. I have tested all the proxies and they work just fine and the really wierd thing is if I shut down the program and restart it again the problems go away. So I'm left to believe that when I'm closing my connection that its really not closing the connection and the computer is being overloaded. How cna i force all socks connections to close that are associated with a class?
socket.Shutdown(SocketShutdown.Both);
//socket.Close();
socket.Disconnect(true);
socket = null;
In reponse to a tip to use netstat I checked it out. I noticed connections where lingering but finally would go away. However, the problem still remains, after about the 100th connection, 5 second pause between connections. I get timeout errors. If I close the proram and restart it they go away. So for some reason I feel that the connections are leaving behind something. Netstat dosent show it. I've even tried adding the instances of the client to a list and each time one is finish remove it from the list and then set it to null. Is there a way to kill a port? Maybe that would work, if I killed the port the connection was being made on? Is it possible this is a Windows OS issue? Something thats used to prevent viruses? I'm making roughly a connection a minute and mainint that connection for about 1 minute before moving on to the next with atleast 20 concurent if not more connections at the same time. What dosent make sense to me is that shuting down the program seem sto clean up whatever resources I'm not cleaning up in my code. I'm using an class I found on the internet that allows socks5 proxies to be used with the socket class. So i'm really at a loss, any advice or direction to head woudl be great? It dosent have to be pretty. I'm have tempted to wite to a text file where I was in my connection list and shutdown the program and then have anohter program restart it to pick up where it left off at this point.
Sounds like your connections aren't really closed. Without seeing the code, it's hard to troubleshoot this; can you boil it down to a program that loops through an open-close sequence?
If the connection doesn't close as expected, you can probably see what state it is in with netstat. Do you have 200 established connections, or are they in some sort of closing state?
Sockets implement IDisposable. Only calling Dispose or Close will cause the socket to give give up the unmanaged resources in a deterministic manner. This is causing you to run out of the resources that the socket uses (probably a network handle of some sort), even though you may not any managed object useing them.
So you should probably just do
socket.Shutdown(SocketShutdown.Both);
socket.Close();
To be clear setting the socket to Null does not do this because setting the socket to null only causes the sockets to be placed on the freachable queue, to have its finalizer called when it gets around to processing the freachable queue.
You may want to review this article which gives a good model on how Unmanaged resources are dealt with in .NET
Update
I checked and Sockets do indeed contain a handle to a WSASocket. So unless you call close or dispose you'll have to wait until the Finalizers run (or exiting the appplication) for you to get them back.
Is it necessary to close the connection of a tcplistener or tcpclient after every message received, or is it possible to close it at a later time while it continues to receive data? Is there any major security issue with leaving it open and listening? I know trojans tend to open a listener and leave it open, will my program be detected as such? Its just a simple chat program....
Thanks for the help!
This is in vb.net.
It depends what the protocol is. If the protocol expects a new connection for each message, then you should close it. (This is like HTTP 1.0.)
If the protocol allows multiple messages to be sent down the same connection, then it's entirely reasonable to leave it open. (This is like HTTP 1.1 and most native database connections.)
I wouldn't expect your connection to be treated with undue suspicion just for keeping open.