|
-
January 20th, 2006, 06:32 PM
#1
Winsock help needed NOW!
I need to find out if data is available to be read from a socket before I read it with recv so I don't have to wait cuz I am gona port my server over from VB to C++ and I'ma gona have a thread that loops through multiple sockets and reads the data and if all the other sockets have to wait for one to recieve data then that is gona suck balls.
So someone please help me to figure out how to retrieve if data is available from a socket.
-
January 20th, 2006, 06:44 PM
#2
Re: Winsock help needed NOW!
-
January 20th, 2006, 06:45 PM
#3
Re: Winsock help needed NOW!
 Originally Posted by Guidosoft
So someone please help me to figure out how to retrieve if data is available from a socket.
You can use 'select()' for example...
-
January 20th, 2006, 06:54 PM
#4
Re: Winsock help needed NOW!
Can you please give me a code example and not just a link to MSDN?
I just need an example of how to find out if I can read data from the socket. I don't need all that other stuff that I already know in the example.
-
January 20th, 2006, 07:05 PM
#5
Re: Winsock help needed NOW!
Something like...
Code:
// Client send function
int Send(void *pvBuffer, int iStillToSend)
{
int iRC = 0;
int iSendStatus = 0;
timeval SendTimeout;
char *pBuffer = static_cast<char *>(pvBuffer);
fd_set fds;
FD_ZERO(&fds);
FD_SET(Socket, &fds);
// Set timeout
SendTimeout.tv_sec = 0;
SendTimeout.tv_usec = 250000; // 250 ms
// As long as we need to send bytes...
while(iStillToSend > 0)
{
iRC = select(0, NULL, &fds, NULL, &SendTimeout);
// Timeout
if(!iRC)
return -1;
// Error
if(iRC < 0)
return WSAGetLastError();
// Send some bytes
iSendStatus = send(Socket, pBuffer, iStillToSend, 0); // Socket is of type
// 'SOCKET' and is
// the current
// connection socket
// Error
if(iSendStatus < 0)
return WSAGetLastError();
else
{
// Update buffer and counter
iStillToSend -= iSendStatus;
pBuffer += iSendStatus;
}
}
return 0;
}
-
January 20th, 2006, 07:56 PM
#6
Re: Winsock help needed NOW!
Thanx but I need to find out if there is data available to be read from a socket this way I don't have to wait for the function. I can just know if there isn't data, and don't run the recv function. I can make a simple loop to go through multiple sockets and recieve data in the same thread without having to wait on one socket that doesn't have any available data to read.
-
January 20th, 2006, 09:01 PM
#7
Re: Winsock help needed NOW!
you can used the same code in the previous post to check that if socket has anything to receive by modifying the select() call from
Code:
iRC = select(0, NULL, &fds, NULL, &SendTimeout);
to
Code:
iRC = select(0, &read_fds, &write_fds, NULL, &SendTimeout);
Where read_fds contains all the sockets to recv() from and write_fds contains all the sockets to send() to. You can add a single socket to both FD_SETS and then when select() returns, use FD_ISSET() to check which set (read or write) has the socket set. If its read set then you can run recv() on that socket to receive the data.
I think you need to read a bit on select() . Read the following link. It has an example too.
http://beej.us/guide/bgnet/output/ht...ed.html#select
-
January 21st, 2006, 01:51 AM
#8
Re: Winsock help needed NOW!
Why dont you run the recv on a different thread? That thread will be blocked, but you can continue your work on the main thread.....
-
January 21st, 2006, 08:40 AM
#9
Re: Winsock help needed NOW!
Oh so your saying I should have 500 threads for each socket?
That is retarded.
I have 2 threads in my application.
1. The GUI Thread - Handles all the GUI crap.
2. The server thread - Handles all the sockets.
I need to make sure that I don't have to wait on sockets. Thats why I am using select().
-
January 21st, 2006, 09:17 AM
#10
Re: Winsock help needed NOW!
 Originally Posted by Guidosoft
Oh so your saying I should have 500 threads for each socket?
That is retarded.
I have 2 threads in my application.
1. The GUI Thread - Handles all the GUI crap.
2. The server thread - Handles all the sockets.
I need to make sure that I don't have to wait on sockets. Thats why I am using select().
Well...this raises another question...how many clients will connect to your server simultaneously? Usually, you don't want to handle them all in one thread but increase performance and scalability by using a multithreaded server...
-
January 21st, 2006, 09:25 AM
#11
Re: Winsock help needed NOW!
500 maximum. Thats why I don't want to use 500 threads. My poor little system can't handle 500 threads.
O, and I have another problem.
When my server accepts a connection, it closes the listening socket and then redoes the listening process by creating, binding, and listening.
However it fails to bind and returns a WSAADDRINUSE error. I don't understand what is wrong. I closed the listening socket before I created a new one and bound it but it didn't bind I just get an error.
PLEASE HELP ME!!!!
-
January 21st, 2006, 10:58 AM
#12
Re: Winsock help needed NOW!
 Originally Posted by Guidosoft
However it fails to bind and returns a WSAADDRINUSE error. I don't understand what is wrong. I closed the listening socket before I created a new one and bound it but it didn't bind I just get an error.
This is a problem related to the TCP stack implementation. For different reasons, a stack implementation can choose to keep the port reserved/locked for a while after it is closed. The safest solution would be to change your design so that you do not need to close it, reopen it and bind it every time.
Here is more information about the error you encounter:
 Originally Posted by msdn
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 ADSDR_ANY), a WAEADDRINUSE 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.
Har Har
-
January 21st, 2006, 11:04 AM
#13
Re: Winsock help needed NOW!
OK, so I am only listening for 1 connections at a time. Now, after I accept,, how do I go back to listening on that port using the same listening socket? Hmm?
I shouldn't have to reconfigure the whole design because I have a functions RefreshLSock() which basically does the close, create, bind and listen. I should just be able to change that function to make it just listen again.
But how do I do that after accepting a connection?
And how come when I click Stop in my server and then Run, it works fine? The stop button closes all the sockets!
And what if I wanted to close, create, bind and listen each time? How would I go about unlocking and unreserving the port so I can?
Also, one more problem?
The select() function won't detect when telnet closes the connection or when any other client does it (I assume). How do I tell when the connection is closed because the function I made that uses select() woin't tell me and the function works flawlessly.
-
January 21st, 2006, 11:37 AM
#14
Re: Winsock help needed NOW!
Hi Andreas,
I used code provided by you a long time back and have found a little bug.
Code:
// Client send function
int Send(void *pvBuffer, int iStillToSend)
{
int iRC = 0;
int iSendStatus = 0;
timeval SendTimeout;
char *pBuffer = static_cast<char *>(pvBuffer);
fd_set fds;
FD_ZERO(&fds);
FD_SET(Socket, &fds);
// Set timeout
SendTimeout.tv_sec = 0;
SendTimeout.tv_usec = 250000; // 250 ms
// As long as we need to send bytes...
while(iStillToSend > 0)
{
iRC = select(0, NULL, &fds, NULL, &SendTimeout);
// Timeout
if(!iRC)
return -1;
// Error
if(iRC < 0)
return WSAGetLastError();
// Send some bytes
iSendStatus = send(Socket, pBuffer, iStillToSend, 0); // Socket is of type
// 'SOCKET' and is
// the current
// connection socket
// Error
if(iSendStatus < 0)
return WSAGetLastError();
else
{
// Update buffer and counter
iStillToSend -= iSendStatus;
pBuffer += iSendStatus;
}
}
return 0;
}
This function FD_SET(Socket, &fds) should be used inside the while(iStillToSend > 0) before calling select.
If you don't do this the select will succeed the first time but then fail even if iStillToSend > 0 (excluding other possible reasons for failure)
Edit: I am not sure if FD_ZERO should also be inside the while....
Last edited by miteshpandey; January 21st, 2006 at 11:48 AM.
If there is no love sun won't shine
-
January 21st, 2006, 07:51 PM
#15
Re: Winsock help needed NOW!
 Originally Posted by Guidosoft
OK, so I am only listening for 1 connections at a time. Now, after I accept,, how do I go back to listening on that port using the same listening socket? Hmm?
The socket you specify in the listen() function will still listen for new incoming connection after a connection has been accepted with the accept() function. The socket descriptor returned by accept() is the socket connected to the client, while the socket descriptor passed as an argument in accept() is unaffected and will still be listening.
The backlog parameter of the listen() function determines the maximum number of connections that can be queued on the listening socket (ie. connections you haven't accepted) before it sends back WSAECONNREFUSED to the client trying to connect.
Last edited by runesvend; January 21st, 2006 at 07:55 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|