Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

TCP WINSOCK CONNECTION

Status
Not open for further replies.

TrueCode

MIS
Sep 30, 2003
71
LC
I Have searched this forum and a number of sites on the subject. However, I am not getting this thing right.


I create two forms with the winsock control on each and each is BINDed to separate ports and IP addresses. I execute the listen() method on the Server in its INIT().

On the client I execute the CONNECT(serverip, serverbindport)
I get the message that I cannot perform this task in this state. Is there something I had to do before executing the CONNECT on the client?.
I am okay with SENDDATA and dataarrival. I have been using UDP. Now I want to use TCP causing I think that it will better serve my purpose.

"I have sought your assistance on this matter because I have exhausted all the help that I can find. You are free to direct me to other source of help"
 
Try setting the RemoteHost/RemoteIP and RemotePort settings first, then issue the connect:
Code:
WITH THISFORM.oleWinSock
   IF .state != sckClosed
      *... The connection isn't idle ... let's close it
      .OBJECT.CLOSE()
   ENDIF
   .protocol = sckTCPProtocol
   *... Remote Host name 
   .remoteHost = m.szTCPHost

   *... Remote Port  
   .remotePort = m.szTCPPort

   *...   '0' to use any available Local Port.  If you've opened a secific 
   *...   port before, you'll have to wait for the ip stack to release it 
   *...   before it can be reused.
   .localPort = 0
   .OBJECT.CONNECT()

   DO WHILE .OBJECT.state < 7
      IF &quot;Visual FoxPro 07&quot; $ VERSION() 
         INKEY(.1)
      ENDIF
      DOEVENTS && we must check for the State
      *... and show it on the form
      IF .state = 9
         MessageBox(&quot;Unable to connect&quot;, 48, 'Host unavailable')

         .OBJECT.CLOSE()
         THISFORM.Release
         RETURN
      ENDIF
   ENDDO
ENDWITH
THISFORM.lConnected = .T.


-Dave S.-
[cheers]
Even more Fox stuff at:
 
sckClosed = 0 here.

These are all defines from a FOXSOCK.H include file.
In case anyone is interested, I will post it below. I forget where it came from now.

FOXSOCK.H
Code:
#DEFINE sckTCPProtocol	0	&& TCP protocol
#DEFINE sckUDPProtocol	1	&& UDP protocol
#DEFINE sckClosed	0	&& Socket is currently closed
#DEFINE sckOpen	1	&& Socket is currently open
#DEFINE sckListening	2	&& Socket is listening for requests
#DEFINE sckConnectionPending	3	&& Socket has a pending request
#DEFINE sckResolvingHost	4	&& Socket is resolving remote computer name
#DEFINE sckHostResolved	5	&& Socket has resolved remote computer name
#DEFINE sckConnecting	6	&& Socket is connecting to remote computer
#DEFINE sckConnected	7	&& Socket has connected to remote computer
#DEFINE sckClosing	8	&& Socket is closing connection to remote computer
#DEFINE sckError	9	&& Socket has encountered an error
#DEFINE sckInvalidPropertyValue	380	&& Invalid property value
#DEFINE sckGetNotSupported	394	&& Property is write-only
#DEFINE sckSetNotSupported	383	&& Property is read-only
#DEFINE sckOutOfMemory	7	&& Out of memory
#DEFINE sckBadState	40006	&& Wrong protocol or connection state for the requested transaction or request
#DEFINE sckInvalidArg	40014	&& The argument passed to a function was not in the correct format or in the specified range
#DEFINE sckSuccess	40017	&& Successful
#DEFINE sckUnsupported	40018	&& Unsupported variant types
#DEFINE sckInvalidOp	40020	&& Invalid operation at current state
#DEFINE sckOutOfRange	40021	&& Argument is out of range
#DEFINE sckWrongProtocol	40026	&& Wrong protocol for the requested transaction or request
#DEFINE sckOpCanceled	10004	&& The operation is canceled
#DEFINE sckInvalidArgument	10014	&& Invalid argument
#DEFINE sckWouldBlock	10035	&& Socket is non-blocking and the specified operation will block
#DEFINE sckInProgress	10036	&& A blocking winsock operation is in progress
#DEFINE sckAlreadyComplete	10037	&& The operation is completed. No blocking operation is in progress.
#DEFINE sckNotSocket	10038	&& The descriptor is not a socket
#DEFINE sckMsgTooBig	10040	&& The datagram is too large to fit into the buffer and is truncated
#DEFINE sckPortNotSupported	10043	&& The specified port is not supported
#DEFINE sckAddressInUse	10048	&& Address in use
#DEFINE sckAddressNotAvailable	10049	&& Address is not available from the local machine
#DEFINE sckNetworkSubsystemFailed	10050	&& Network subsystem failed
#DEFINE sckNetworkUnreachable	10051	&& The network cannot be reached from this host at this time
#DEFINE sckNetReset	10052	&& Connection has timed out when SO_KEEPALIVE is set
#DEFINE sckConnectAborted	10053	&& Connection is aborted due to timeout or other failure
#DEFINE sckConnectionReset	10054	&& The connection is reset by remote side
#DEFINE sckNoBufferSpace	10055	&& No buffer space is available
#DEFINE sckAlreadyConnected	10056	&& Socket is already connected
#DEFINE sckNotConnected	10057	&& Socket is not connected
#DEFINE sckSocketShutdown	10058	&& Socket has been shut down
#DEFINE sckTimedout	10060	&& The attempt to connect timed out
#DEFINE sckConnectionRefused	10061	&& Connection is forcefully rejected
#DEFINE sckNotInitialized	10093	&& WinsockInit should be called first
#DEFINE sckHostNotFound	11001	&& Authoritative answer: Host not found
#DEFINE sckHostNotFoundTryAgain	11002	&& Non-Authoritative answer: Host not found
#DEFINE sckNonRecoverableError	11003	&& Non-recoverable errors
#DEFINE sckNoData	11004	&& Valid name, no data record of requested type


-Dave S.-
[cheers]
Even more Fox stuff at:
 
DaveS

Are you suggesting that I ahould not BIND() local port. Or is setting the localport property doing the same thing?


&quot;I have sought your assistance on this matter because I have exhausted all the help that I can find. You are free to direct me to other source of help&quot;
 
Setting the localport property to 0, is basically looking for the first unused 'outgoing' port to connect to the remote host. (eg., SELECT 0...USE MyTable...)
Setting the localport property to a value other than 0 could cause a state error if the previous instance of winsock was already had that port open, and either hasn't been released properly itself, or the port hasn't been released properly and hasn't had enough WAIT time for the IP stack to forcibly release it.


-Dave S.-
[cheers]
Even more Fox stuff at:
 
Dave, after running your code, I issued a SUSPEN to examine the state of the control. I was expecting a 7, state instead of an 8 which means closing connection.

Also, I have one client interacting with two servers. Each has to send messages to it at different times and it them. Now I have to test the state of the connection to both from the client. Should I setup two winsock controls on the client? One for each server.


&quot;I have sought your assistance on this matter because I have exhausted all the help that I can find. You are free to direct me to other source of help&quot;
 
The use of the terms &quot;client&quot; and &quot;server&quot; imply that the client is initiating the connection to each of the servers. When your programs are on both ends of the connection, essentially the only thing to determine what side starts the connection is: Can *this* computer &quot;find&quot; *that* computer? Then *this* computer can be client, and initiate the connection.

It sounds like each server has to be able to spontaneously contact the client with a message, so I'd say, Yes, you do need to maintain two separate connections (two separate winsock controls) on the client, each connected to its respective server, so that the server(s) can spontaneously send something down the connection.

If both endpoints are fixed, then your UDP protocol was sufficient. If you're changing to TCP because the client is now not fixed (the server(s) don't arbitrarily know how to &quot;find&quot; it), then you need to keep the TCP connections open as long as it's possible that the server needs to respond with a message.

Alternatively, the client could give the server the clients IP address during an initial connection, close that connection, then wait for the &quot;server&quot; (now acting as a &quot;client&quot;) to connect-back to send any message. This is how FTP works, however this has the inherent flaw that it doesn't work through most firewalls without specific configuration of the firewall
 
The reason why I am leaving UDP is because I want to know whether the Target pc is reachable first, before doing a datasend.....
I was trying not to find that out after the datasend failed and the error pops.

With TCP, I would test that by the STATE of the control being equal to 8.


------------------------------------->

&quot;I have sought your assistance on this matter because I have exhausted all the help that I can find. You are free to direct me to other source of help&quot;
 
... I was expecting a 7, state instead of an 8 ...
Throw a DEBUGOUT .state clause in and see if by chance you get a 7, then an 8. Maybe it is the remote instance closing your connection.
Code:
DO WHILE .OBJECT.state < 7
   IF &quot;Visual FoxPro 07&quot; $ VERSION() 
      INKEY(.1)
   ENDIF
   DOEVENTS && we must check for the State

DEBUGOUT .state
Code:
   *... and show it on the form
   IF .state = 9
      MessageBox(&quot;Unable to connect&quot;, 48, 'Host unavailable')

      .OBJECT.CLOSE()
      THISFORM.Release
      RETURN
   ENDIF
ENDDO

Also, I have one client interacting with two servers.
I believe you will need separate controls for each connection (including separate ports), whether it be on the client side talking to 2 servers, or the server side allowing 2 clents. As far as I know, each control will only handle 1 connection at a time.


-Dave S.-
[cheers]
Even more Fox stuff at:
 
I think Dave's right: One control/one connection.

If it's the server handling 2+ clients, it can have just one control waiting for connections, then when it sees one coming in, it can create an object (say, a form) containing another control, and let this &quot;spawned&quot; form handle this new connection, while the original control remains listening for more connections.

ie: Setup your first winsock control listening on the right port,
in the ConnectionRequest event, do this:
Create another form, handing it the incoming RequestID
The new form, should do this:
PARAMETERS pcReqID
if THISFORM.Sock.State<>sckClosed
THISFORM.Sock.Close
endif
THISFORM.Sock.Accept( pcReqID )
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top