feefle
March 3rd, 2003, 10:52 AM
Does anyone know of an easy way to set a socket option,
like the reuse option, using a csocket?
like the reuse option, using a csocket?
| // JP opened flex table
Click to See Complete Forum and Search --> : CSocket and Socket Options feefle March 3rd, 2003, 10:52 AM Does anyone know of an easy way to set a socket option, like the reuse option, using a csocket? Andreas Masur March 3rd, 2003, 10:56 AM You can use the inherited 'SetSockOpt()' from 'CAsyncSocket' thus BOOL fOptval = TRUE; CSocket Socket; // Initialization etc. if(Socket.SetSockOpt(SO_REUSEADDR, &fOptval, sizeof(BOOL)) == FALSE) // Error -> call ::GetLastError() feefle March 3rd, 2003, 06:38 PM The ReuseAddr option must be set at a certain time during the sockects creation. Are you sure that CSocket will let you set that option at the correct time in it's creation of the actual socket? I think the point at which this socket option must be set is somewhere in the section that CSocket implements when you call "new" to create a new CSocket object. I would like to allow two different applications to bind to the same port at the same time on the same machine using a CSocket. Andreas Masur March 4th, 2003, 02:33 AM I think there is a misunderstanding about 'SO_REUSEADDR'. This option is not intended to allow more than one application to use the same socket but rather the same application to re-use the same socket again even if it is still in the TIME_WAIT state... Basically the same question was asked two weeks ago in this thread (http://www.codeguru.com/forum/showthread.php?s=&threadid=230450).... feefle March 4th, 2003, 12:57 PM Okay. Do you know of any options that can be used with CSocket that will allow two seperate applications on the same machine to open a socket on the same port at the same time? feefle March 4th, 2003, 01:00 PM P.S., I know how to do this using a normal BSD socket as well as an CASyncsocket. I need to know how to do it using a CSocket. Richard.J March 4th, 2003, 01:25 PM main difference between CSocket and CAsyncSocket is that CSocket is blocking. If you know how to share a socket, would you mind telling me? From my point of view it is not possible, and I have stated that several times here. Richard feefle March 4th, 2003, 02:26 PM I'm not sure on how to share a socket. What I am trying to do is have two seperate sockets on the same machine that open the same port. This can be done by setting the socket options but this particular option must be set at a time I think before it is opened. The constructor in CSocket does all this for you and so by the time you could make a call to set this option, it won't do anything. The reason I want to use CSocket is that it has all the serialization built in. If I use CAsyncsocket I'll have to add all the serialization code. Something I don't really feel like doing. Richard.J March 4th, 2003, 02:39 PM ok, you have 2 apps, each of them opening a socket on the same port. And as far as I understood, you would like to set the SO_REUSEADDR on the socket to achieve this, right? In this case, Andreas Masur's post applies: the option does not allow several apps to use the same port, but leads to an invalid socket in the first app as soon as the second app binds to the port. The option is only intended to allow for quick server restarts in case the socket/port is not yet released by the OS (e. g. due to a previous server crash). It might be possible to open 2 sockets on the same port with different protocols, but I never tried that. Richard Andreas Masur March 4th, 2003, 03:46 PM Well...it looks like that I am wrong. After thinking a little bit about the thing and also the expected behaviour by Richard with using 'bind' I decided to refresh my knowledge a little bit... And I think, it should be possible using the mentioned 'SO_REUSEADDR' socket option. If I consider the scenario the following should happen: The first application will bind the socket to the port. When the second application tries it, 'bind()' should return with the error 'WSAEADDRINUSE' (10048)... From MSDN: WSAEADDRINUSE (10048) Address already in use. Typically, only one usage of each socket address (protocol/IP address/port) is permitted. This error occurs if an application attempts to bind a socket to an IP address/port that has already been used for an existing socket, or a socket that was not closed properly, or one that is still in the process of closing. For server applications that need to bind multiple sockets to the same port number, consider using setsockopt(SO_REUSEADDR). Client applications usually need not call bind at all—connect chooses an unused port automatically. When bind is called with a wildcard address (involving ADDR_ANY), a WSAEADDRINUSE error could be delayed until the specific address is committed. This could happen with a call to another function later, including connect, listen, WSAConnect, or WSAJoinLeaf. That basically leads to me to the conclusion that it is possible to bind more than socket to one port address... I did not test it yet though.... Richard.J March 5th, 2003, 12:05 PM Andreas, you have made me curious! I have set up a test: if you create a server that calls setsockopt for SO_REUSEADDR and start 2 instances of this server, a client will connect to one of these instances. If you close one instance, the client connects to the other instance. Which instance the client connects to is unpredictable for me. If you create 2 servers, the first that does not call setsockopt and a second that does, the behaviour is the same. I wouldn't have guessed that this is possible. I stop testing here. PeterPurple November 26th, 2005, 12:19 PM I realize this is an old post, but some people who come along here (like me) may be interested in the answer. Some of the above is very misleading. CAsyncSocket does not allow REUSEADDR because create creates the socket and immediately calls bind. Therefore there is no opportunity to insert the reuseaddr between the two calls. I worked around by copying the create method and using it to derive my own with the additional call to SetSockOpt() - I'm kind of lucky the method it calls were public. Too bad create is not virtual. See code below. The reuseaddr works fine, I have several .exes receiving multicast message on the one port. Note (according to MS) the first person to open the port must set reuseaddr. You cannot use reuseaddr to steal stuff from others, this is something which has been 'fixed' as some viruses we wreaking havoc. Pierre Laviolette. Montreal. BOOL CMulticastSocket::CreateReuseSocket(UINT nSocketPort, int nSocketType, long lEvent, LPCTSTR lpszSocketAddress) { if (Socket(nSocketType, lEvent)) { BOOL bMultipleApps = TRUE; /* allow reuse of local port if needed */ int rc = SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET); if (!rc) { // TODO: Fix this properly!!! int lError = GetLastError(); } if (Bind(nSocketPort,lpszSocketAddress)) return TRUE; int nResult = GetLastError(); Close(); WSASetLastError(nResult); } return FALSE; } Marc G November 26th, 2005, 12:48 PM [ moved thread ] codeguru.com
Copyright 2007 Jupitermedia Corporation All Rights Reserved. |