File descriptors across threads.

I am running MSVC++ 6.0 (sp3) on WinNT 4.0ws (sp5).

I am trying to create a some basic concurrent server-client functionality. I have ported code from a unix platform and managed to get it compiled with a little giggery-pokery, but I have a painful bug.

The server side calls runBasicServer() with some params. This spawns a thread (with CreateThread()) and then starts a listener, socket(), bind(), listen(), select(). This is fine and it sees connection requests, and then spawns off another thread to handle the connection via a passed function pointer. The first thing I do, is do a read, since it is non-blocking, i expect a zero to come back from read(). Nope, I get a -1. This is an error so the server disconnects, and thats it.

On the client side, I use a runBasicClient() this connects and then spawns a thread to run the passed client function. THe first thing I do is a write, expecting the number of bytes I wrote... -1... error, client quits.

Because of the server functioning partly correctly, I am assuming the CreateThread does not allow the passing of file descriptors over the thread boundary? I can't seem to find this documented, but it does seem reminiscent somewhere.

How do I use CreateThread() or similar to allow the open file descriptors to be inherited by the child thread?

Worst case, I could spawn the client earlier not providing a status, but I really do want a concurrent server.
nigel5Asked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
jkrConnect With a Mentor Commented:
Socket descriptors cam be passed over thread boundaries (doing this a lot).

The following sample (though it's using a 3rd party library) illustrates how to do it:

ULONG   __stdcall   SockLibCommThread         (   LPVOID)
{
    HANDLE  hThread =   NULL;
    DWORD   dwTID;

    TSocket sSrvSock    =   SOCK_ERR;
    TSocket sClntSock   =   SOCK_ERR;

    SockLibSetService   (   _SERVICE_NAME);

    if  (   SOCK_ERR    ==  (   sSrvSock    =   SockLibListenSock ()))
        {

            SockLibPrintErrorStack  (   stdout);

            return  (   -1);
        }

    while   (   TRUE)
            {
                sClntSock   =   SockLibWaitForConnectingSock    (   sSrvSock);

                if  (   SOCK_ERR    ==  sClntSock)
                        break;

                if  (   hThread)
                        WaitForSingleObject (   hThread,    INFINITE);

                hThread =   CreateThread    (   NULL,
                                                0,
                                                WorkerThread,
                                                ( LPVOID) sClntSock,
                                                0,
                                                &dwTID
                                            );

    }

    SockLibCloseSock    (   sSrvSock);

    return  (   0);
}

ULONG   __stdcall   WorkerThread           (   LPVOID      pv)
{
    SOCKLIBRET slr;

    char*   pcBuf   =   NULL;

    TSocket sClntSock   =   ( TSocket)  pv;

    slr =   ReceiveBuffer   (   &pcBuf);

    SockLibCloseSock    (   sClntSock);

    return  (   0);
}

The 1st thread waits for incoming connections, and once a client connects, it spawns another thread to handle the communication.

Feel free to ask if you need more information!
0
 
nigel5Author Commented:
I dont doubt that you can pass objects, even CSocket type objects, but using standard integer file descriptors?

If ths is the default action, then why would a read() and write() (standard C library calls) both fail with a -1 status (this, on unix anyhow, means that the socket has been closed.), when the only thing I have done is started a new thread?
0
 
jkrCommented:
Hmm, the above 'TSocket' type is nothing but a standard integer file descriptor (no MFC, this lib is just a 'wrapper' for both Winsock and BSD).

Do both threads access the descriptor simultaneously?
0
 
ufolk123Commented:
Hi nigel5,

I understood your problem correctly.I faced the same problem while porting a multithreaded socket
code from Unix to NT.
Basically the problem is that read() and write() of  C Run-time on windows  should not be used for sockets.Ther are
basically meant for File IO.
You please try to change _read() and_write() to
send() and recv() and pass extra last parameter as default.
You can alternatively use ReadFile() and WriteFile() of win32 but it may introduce more code difference between Unix and Windows.


Regards,
ufolk123
0
All Courses

From novice to tech pro — start learning today.