Click here to Skip to main content
Click here to Skip to main content

Network Transfer Of Files Using MFC's CSocket Class

, 31 Oct 2004
Rate this:
Please Sign up or sign in to vote.
How to use CSocket to transfer files from one computer to another over a netwok or the Internet.

Using CSocket to transferring files between computers over a network

Contents

  1. Introduction
  2. Server-Side Code
  3. Client-Side Code
  4. Demo Software

Introduction

This brief article shows how to use MFC's CSocket class to transfer files (large files or small files -- it doesn't matter) from one computer to another over a network or the Internet. There is no attempt made to describe the Winsock API or how sockets work, nor is there even an attempt to describe the CSocket class. But if you read this article, and understand why things were done and when they were done, you should come away with a better appreciation of sockets.

Transferring files with CSocket is not too difficult, but it's also easy to make mistakes. One of the most common mistakes is a failure to check the return values from the various CSocket function calls. This might stem from a basic misunderstanding of how sockets work. Most beginners view sockets like a pipe, where if you shove information into one end, it pops out the other. This view is not totally inaccurate, since a streaming socket (see footnote 1) will guarantee that, once accepted, information from a source will be delivered to a recipient and will be delivered in the correct order. But sockets are particular about the information that you try to "shove into the pipe", and there might be occasions where the socket will not accept the information. Likewise, although all information accepted by the socket will be delivered, there is no one-for-one correspondence between the number of bytes sent by one call to CSocket::Send() (on the sending side) and one call to CSocket::Receive() (on the receiving side). For example, if one call to CSocket::Send() sends 10 bytes, then one call to CSocket::Receive() might retrieve 10 bytes, or it might retrieve only one byte, or any number in between. As a result, the recipient might need to call CSocket::Receive() multiple times before all 10 bytes are received.

On top of that, virtually anything can go wrong during socket communications. The client might disconnect, the server might timeout, the network cable might become disconnected. This adds the element of error-checking on top of an already complicated situation.

All the CSocket functions tell you what they did, and whether they did it successfully, in their return values. The key to successfully transferring files, therefore, is a careful monitoring of the return value from each call.

Server-Side Code

Let's dive into the code and then explain what each part does. Here's code for sending a file from the computer that hosts the file (we'll call this the "server", based on convention) to another computer that asks for it (the "client").

#define PRE_AGREED_PORT        8686
#define SEND_BUFFER_SIZE    4096

BOOL CYourServerClass::SendFileToRemoteRecipient(CString fName)
{
    /***************************
    // listens for a connection from a remote client and uploads a file to it
    // the remote client must be running
    // a counterpart GetFileFromRemoteSender function
    // Input: CString fName = name of local file 
    //        which will be uploaded to remote client
    // Output: BOOL return value indicates success or failure of the upload
    ***************************/
    
    // create socket and listen on pre-designated port

    ///    AfxSocketInit(NULL);
    // make certain this is done somewhere in each thread
    // (usually in InitInstance for main thread)
    CSocket sockSrvr; 
    // Creates our server socket
    sockSrvr.Create(PRE_AGREED_PORT);
    // Start listening for the client at PORT
    sockSrvr.Listen();
    CSocket sockConnection;
    // Use another CSocket to accept the connection
    sockSrvr.Accept(sockConnection);
    
    // local variables used in file transfer (declared here
    // to avoid "goto skips definition"-style compiler errors)

    // return value
    BOOL bRet = TRUE;
    // used to monitor the progress of a sending operation
    int fileLength, cbLeftToSend;
    // pointer to buffer for sending data
    // (memory is allocated after sending file size)
    BYTE* sendData = NULL;

    CFile sourceFile;
    CFileException fe;
    BOOL bFileIsOpen = FALSE;
    
    if( !( bFileIsOpen = sourceFile.Open( fName, 
           CFile::modeRead | CFile::typeBinary, &fe ) ) )
    {
        TCHAR strCause[256];
        fe.GetErrorMessage( strCause, 255 );
        TRACE( "SendFileToRemoteRecipient encountered 
          an error while opening the local file\n"
          "\tFile name = %s\n\tCause = %s\n\tm_cause = %d\n\tm_IOsError = %d\n",
          fe.m_strFileName, strCause, fe.m_cause, fe.m_lOsError );
        
        /* you should handle the error here */
        
        bRet = FALSE;
        goto PreReturnCleanup;
    }

    // first send length of file

    fileLength = sourceFile.GetLength();
    fileLength = htonl( fileLength );

    cbLeftToSend = sizeof( fileLength );

    do
    {
        int cbBytesSent;
        BYTE* bp = (BYTE*)(&fileLength) + sizeof(fileLength) - cbLeftToSend;
        cbBytesSent = sockConnection.Send( bp, cbLeftToSend );
        
        // test for errors and get out if they occurred
        if ( cbBytesSent == SOCKET_ERROR )
        {
            int iErr = ::GetLastError();
            TRACE( "SendFileToRemoteRecipient returned a socket
                error while sending file length\n"
                "\tNumber of Bytes sent = %d\n"
                "\tGetLastError = %d\n", cbBytesSent, iErr );
            
            /* you should handle the error here */

            bRet = FALSE;
            goto PreReturnCleanup;
        }
        
        // data was successfully sent, so account
        // for it with already-sent data
        cbLeftToSend -= cbBytesSent;
    }
    while ( cbLeftToSend>0 );
    
    
    // now send the file's data    
    sendData = new BYTE[SEND_BUFFER_SIZE]; 
    
    cbLeftToSend = sourceFile.GetLength();
    
    do
    {
        // read next chunk of SEND_BUFFER_SIZE bytes from file
        
        int sendThisTime, doneSoFar, buffOffset;
        
        sendThisTime = sourceFile.Read( sendData, SEND_BUFFER_SIZE );
        buffOffset = 0;
        
        do
        {
            doneSoFar = sockConnection.Send( sendData + buffOffset, 
                                                    sendThisTime ); 
            
            // test for errors and get out if they occurred
            if ( doneSoFar == SOCKET_ERROR )
            {
                int iErr = ::GetLastError();
                TRACE( "SendFileToRemoteRecipient returned a socket error 
                    while sending chunked file data\n"
                    "\tNumber of Bytes sent = %d\n"
                    "\tGetLastError = %d\n", doneSoFar, iErr );
                
                /* you should handle the error here */
                
                bRet = FALSE;
                goto PreReturnCleanup;
            }
            
            // data was successfully sent,
            // so account for it with already-sent data
            
            buffOffset += doneSoFar;
            sendThisTime -= doneSoFar;
            cbLeftToSend -= doneSoFar;
        }
        while ( sendThisTime > 0 );
        
    }
    while ( cbLeftToSend > 0 );
    
    
PreReturnCleanup: // labelled goto destination
    
    // free allocated memory
    // if we got here from a goto that skipped allocation,
    // delete of NULL pointer
    // is permissible under C++ standard and is harmless
    delete[] sendData;
    
    if ( bFileIsOpen )
        sourceFile.Close();
        // only close file if it's open (open might have failed above)
    
    sockConnection.Close();
    
    return bRet;

}

There are three major functions performed by this code: first listen for and establish a connection with the client, next send the client the length of the file, and then finally send the file to the client in chunks. In the first part, the code creates a CSocket object named sockSrvr and configures it to listen on a pre-designated port (which is #define'd as 8686 and must be known to the server). When a connection request is received on the port, a second CSocket object named sockConnection is created to handle the connection. The connection is accepted by the sockConnection object in the call to CSocket::Accept(), which actually hands the connection off to a new port address, leaving sockSrvr free to listen for further connection requests on the originally-designated port. All very standard.

After the connection is accepted, the server imposes a very simple protocol on the file transfer. Before actual transfer of file data, the server sends the total length of the file (in bytes). Let's look at that code in detail:

    // first send length of file
    
    fileLength = sourceFile.GetLength();
    fileLength = htonl( fileLength );
    
    cbLeftToSend = sizeof( fileLength );
    
    do
    {
        int cbBytesSent;
        BYTE* bp = (BYTE*)(&fileLength) + sizeof(fileLength) - cbLeftToSend;
        cbBytesSent = sockConnection.Send( bp, cbLeftToSend );
        
        // test for errors and get out if they occurred
        if ( cbBytesSent == SOCKET_ERROR )
        {
            int iErr = ::GetLastError();
            TRACE( "SendFileToRemoteRecipient returned 
                a socket error while sending file length\n"
                "\tNumber of Bytes sent = %d\n"
                "\tGetLastError = %d\n", cbBytesSent, iErr );
            
            /* you should handle the error here */

            bRet = FALSE;
            goto PreReturnCleanup;
        }
        
        // data was successfully sent,
        // so account for it with already-sent data
        cbLeftToSend -= cbBytesSent;
    }
    while ( cbLeftToSend>0 );

CFile::GetLength() retrieves the file's length in bytes, and the next function, htonl(), compensates for differences in machines that store integers in big-endian versus little-endian format (see footnote 2). The interesting part happens next: a loop is entered to send the length of the file to the client. In the loop, CSocket::Send() is called repeatedly until all bytes of the file's length are sent to the client.

Why is a loop needed? Well, as indicated above, sockets are particular about whether or not they will accept information for transmission. There might be reasons why the socket is not prepared to accept your data, or is not prepared to accept all of it right now. The documentation for CSocket::Send() clearly warns of this (actually, it's the documentation for CAsyncSocket::Send(), which is the base class for CSocket; see MSDN):

Quote from MSDN:

"If no error occurs, Send returns the total number of characters sent. (Note that this can be less than the number indicated by nBufLen.) Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling GetLastError....

On CAsyncSocket objects of type SOCK_STREAM, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both the local and foreign hosts."

It's therefore possible that a single call to CSocket::Send() will not result in a transmission of all four bytes of the integer that stores the file's length. So, we check the return value of Send(), and until all four bytes are sent, we keep on calling it.

We also check rigorously for errors. CSocket::Send() will report on errors in the return code, and if a value of SOCKET_ERROR is returned, then some error has occurred. We determine the precise nature of the error through the following call to GetLastError(). You should handle the error appropriately. The sample code does nothing except a TRACE output to the debug window, followed by an immediate return with a return code of FALSE.

After the length of the file is sent, we send the actual bytes of the file itself. The file is sent in chunks of SEND_BUFFER_SIZE bytes (which we have #define'd as 4096), and we allocate memory from the heap for this buffer. Then, we call CFile::Read() to read chunks of the file one after the other, and send the chunks out over the socket. Let's look at the code:

    // now send the file's data

    sendData = new BYTE[SEND_BUFFER_SIZE];

    cbLeftToSend = sourceFile.GetLength();

    do
    {
        // read next chunk of SEND_BUFFER_SIZE bytes from file
        
        int sendThisTime, doneSoFar, buffOffset;
        
        sendThisTime = sourceFile.Read( sendData, SEND_BUFFER_SIZE );
        buffOffset = 0;

        do
        {
            doneSoFar = sockConnection.Send( sendData + buffOffset, 
                                                     sendThisTime ); 

            // test for errors and get out if they occurred
            if ( doneSoFar == SOCKET_ERROR )
            {
                int iErr = ::GetLastError();
                TRACE( "SendFileToRemoteRecipient returned a socket error 
                    while sending chunked file data\n"
                    "\tNumber of Bytes sent = %d\n"
                    "\tGetLastError = %d\n", doneSoFar, iErr );
                
                /* you should handle the error here */
                
                bRet = FALSE;
                goto PreReturnCleanup;
            }

            // data was successfully sent, so account
            // for it with already-sent data
            
            buffOffset += doneSoFar;
            sendThisTime -= doneSoFar;
            cbLeftToSend -= doneSoFar;
        }
        while ( sendThisTime > 0 );

    }
    while ( cbLeftToSend > 0 );

The integer sendThisTime stores the number of bytes returned by CFile::Read(), and is a convenient way to monitor the last read operation (before EOF) which naturally will contain less than SEND_BUFFER_SIZE bytes. Again, we call CSocket::Send() in a loop, until all of the sendThisTime bytes are actually accepted by the socket and sent out over the network to the client, checking for errors all along the way.

Client-Side Code

Now, let's look at the client-side code:

#define PRE_AGREED_PORT        8686
#define RECV_BUFFER_SIZE    4096

BOOL CYourClientClass::GetFileFromRemoteSender(CString strIP, 
                                               CString fName)
{
    /***************************
    // connects to a remote server and downloads a file from it
    // the remote server must be running a counterpart
    // SendFileToRemoteRecipient function
    // Inputs: CString strIP = IP address of remote server,
    //         in dotted IP format (like "127.0.0.1") or a manchine
               name (like "localhost")
    //         CString fName = name of local file to which
    //         downlaoded data will be stored
    // Output: BOOL return value indiactes success or failure of the download
    ****************************/

    // create client socket and connect to server
    
    ///    AfxSocketInit(NULL);
    // make certain this is done somewhere in each thread
    // (usually in InitInstance for main thread)
    CSocket sockClient;
    sockClient.Create();
    // PRE_AGREED_PORT is #define'd as 8686
    sockClient.Connect( strIP, PRE_AGREED_PORT );
    
    
    // local variables used in file transfer (declared here to avoid
    // "goto skips definition"-style compiler errors)
    
    BOOL bRet = TRUE; // return value
    // used to monitor the progress of a receive operation
    int dataLength, cbBytesRet, cbLeftToReceive;
    // pointer to buffer for receiving data
    // (memory is allocated after obtaining file size)
    BYTE* recdData = NULL;
    
    CFile destFile;
    CFileException fe;
    BOOL bFileIsOpen = FALSE;
    
    // open/create target file that receives the transferred data
    
    if( !( bFileIsOpen = destFile.Open( fName, CFile::modeCreate | 
           CFile::modeWrite | CFile::typeBinary, &fe ) ) )
    {
        TCHAR strCause[256];
        fe.GetErrorMessage( strCause, 255 );
        TRACE( "GetFileFromRemoteSender encountered 
          an error while opening the local file\n"
          "\tFile name = %s\n\tCause = %s\n\tm_cause = %d\n\tm_IOsError = %d\n",
          fe.m_strFileName, strCause, fe.m_cause, fe.m_lOsError );
        
        /* you should handle the error here */
        
        bRet = FALSE;
        goto PreReturnCleanup;
    }
    
    
    // get the file's size first
    cbLeftToReceive = sizeof( dataLength );
    
    do
    {
        BYTE* bp = (BYTE*)(&dataLength) + sizeof(dataLength) - cbLeftToReceive;
        cbBytesRet = sockClient.Receive( bp, cbLeftToReceive );
        
        // test for errors and get out if they occurred
        if ( cbBytesRet == SOCKET_ERROR || cbBytesRet == 0 )
        {
            int iErr = ::GetLastError();
            TRACE( "GetFileFromRemoteSite returned 
              a socket error while getting file length\n"
              "\tNumber of Bytes received (zero means connection was closed) = %d\n"
              "\tGetLastError = %d\n", cbBytesRet, iErr );
            
            /* you should handle the error here */
            
            bRet = FALSE;
            goto PreReturnCleanup;
        }
        
        // good data was retrieved, so accumulate
        // it with already-received data
        cbLeftToReceive -= cbBytesRet;
        
    }
    while ( cbLeftToReceive > 0 );

    dataLength = ntohl( dataLength );

    // now get the file in RECV_BUFFER_SIZE chunks at a time
    
    recdData = new byte[RECV_BUFFER_SIZE];
    cbLeftToReceive = dataLength;
    
    do
    {    
        int iiGet, iiRecd;

        iiGet = (cbLeftToReceive<RECV_BUFFER_SIZE) ? 
                      cbLeftToReceive : RECV_BUFFER_SIZE ;
        iiRecd = sockClient.Receive( recdData, iiGet );

        // test for errors and get out if they occurred
        if ( iiRecd == SOCKET_ERROR || iiRecd == 0 )
        {
            int iErr = ::GetLastError();
            TRACE( "GetFileFromRemoteSite returned a socket error 
                while getting chunked file data\n"
                "\tNumber of Bytes received (zero means connection was closed) = %d\n"
                "\tGetLastError = %d\n", iiRecd, iErr );
            
            /* you should handle the error here */
            
            bRet = FALSE;
            goto PreReturnCleanup;
        }

        // good data was retrieved, so accumulate
        // it with already-received data
        
        destFile.Write( recdData, iiRecd); // Write it
        cbLeftToReceive -= iiRecd;

    } 
    while ( cbLeftToReceive > 0 );

PreReturnCleanup: // labelled "goto" destination
    
    // free allocated memory
    // if we got here from a goto that skipped allocation,
    // delete of NULL pointer
    // is permissible under C++ standard and is harmless
    delete[] recdData;        
    
    if ( bFileIsOpen )
        destFile.Close();
        // only close file if it's open (open might have failed above)
    
    sockClient.Close();
    
    return bRet;
}

There are many parallels between the client-side code and that of the server, and we'll try to avoid redundancy in the explanations. As before, there are three main parts: making a connection, getting the file's length, and then getting the file's data in chunks. In the first part, a CSocket object named sockClient is created and attempts a connection to the server on the pre-designated port. The address of the server is specified by the CString object named strIP which can store either a dotted IP address or a machine name. Once the connection is made, the second part calls CSocket::Receive() in a loop to get the length of the file, which is converted by the ntohl() function into big-endian or little-endian format as appropriate. In the third part, a BYTE buffer of size RECV_BUFFER_SIZE is allocated from the heap, and CSocket::Receive() is called in a loop until all bytes of the file are received. Note that RECV_BUFFER_SIZE can be different from SEND_BUFFER_SIZE, although in this code, they are the same (both are #define'd to 4096). Here's the code for the third part:

    // now get the file in RECV_BUFFER_SIZE chunks at a time
    
    recdData = new byte[RECV_BUFFER_SIZE];
    cbLeftToReceive = dataLength;
    
    do
    {    
        int iiGet, iiRecd;
        
        iiGet = (cbLeftToReceive<RECV_BUFFER_SIZE) ? 
                 cbLeftToReceive : RECV_BUFFER_SIZE ;
        iiRecd = sockClient.Receive( recdData, iiGet );
        
        // test for errors and get out if they occurred
        if ( iiRecd == SOCKET_ERROR || iiRecd == 0 )
        {
            int iErr = ::GetLastError();
            TRACE( "GetFileFromRemoteSite returned a socket error 
                while getting chunked file data\n"
                "\tNumber of Bytes received (zero means 
                connection was closed) = %d\n"
                "\tGetLastError = %d\n", iiRecd, iErr );
            
            /* you should handle the error here */
            
            bRet = FALSE;
            goto PreReturnCleanup;
        }
        
        // good data was retrieved,
        // so accumulate it with already-received data
        
        destFile.Write( recdData, iiRecd); // Write it
        cbLeftToReceive -= iiRecd;

    } 
    while ( cbLeftToReceive > 0 );

The only tricky part of this code is the determination of the number of bytes to ask for in CSocket::Receive(). We want to get as many bytes as possible, up to the size of the buffer, except in the last call to CSocket::Receive(), in which we want only the remaining bytes in the file. The C++ ternary operation (i.e., (condition)?(cond=TRUE):(cond=FALSE)) is used for this purpose.

Note that the code works even if CSocket::Receive() does not retrieve the number of bytes requested. For example, suppose we asked for 4096 bytes (i.e., iiGet == 4096) but CSocket::Receive() only returns 2143 bytes. That's OK; we only write the number of bytes actually received, and we update the remainder in the number of bytes left to receive based only on the number actually received, not the number we asked for.

Demo Software

The "Source" download is a single C++ file containing the above source code. You'll need to adapt the code into your client and server applications, and (for example) must change the CYourServerClass and CYourClientClass namespaces to match your own classes.

The "Demo" download includes a VC++ 6.0 workspace that contains two projects (the client and the server), each implementing the above functions in threads (see footnote 3). This download also contains release-build versions of both executables, so you can test the programs without the need to build them first. Additionally, there are some minor modifications to the code for the above functions, so as to allow them to communicate status results back to the main GUI.

To use, start up the server on a first computer, give it a local file name, and then press the "Listen For Connection Attempt" button. This starts up the thread and puts the server's sockSrvr object into a wait state listening for connection attempts.

Start up the client and type in the name you want used for local storage of the copied file. The client and server can run on the same computer or on different computers -- your choice -- and if they run on different computers, the computers can connect over a local network (wired or wireless) or over the Internet (all combinations have been tested). Give the client the IP address of the server; there's a drop-down box for commonly-used IP addresses for home networks, and use the localhost address of 127.0.0.1 if the client and server are both running on the same computer. Click the "Get File From This Location" button, and the client will connect to the server and be sent a copy of the file. Please remember to put the server into its listening mode before the client tries to connect to it, or nothing will work.

The programs both have counters which display the number of times a send or receive "mismatch event" occurs. A "mismatch event" is a term I coined to refer to a situation where a call to CSocket::Send() did not result in the transmission of all bytes requested (on the server side), or a situation where a call to CSocket::Receive() did not result in receipt of all bytes requested (on the client side). There's a check box in each program that deliberately injects mismatch events artificially, so that you can check on the robustness of the file transfer even in the presence of many mismatch events.

Footnotes

  1. This article will only address streaming protocols (i.e., SOCK_STREAM) which is what most people think of when discussing the Internet's TCP/IP protocol. It will not discuss datagram protocols (i.e., SOCK_DGRAM) which is an unreliable (but sometimes very useful) connectionless protocol that uses UDP.
  2. This is really needless overkill, but it's included here for emphasis. htonl() is used to ensure platform independence of raw socket code, and to ease porting issues form one machine to another. Since we're using CSocket, there's no chance that the code will be used on anything but a Windows/Intel platform.
  3. The threads have a few "non-optimal" aspects, and you should therefore not model your code on them. For example, there are a few instances of shared access to variables with the protection of a synchronization object (like a CCriticalSection). Worse, once the thread has started, there's no way for the user to abort it, short of closing the entire program. Rather, the thread must come to a normal end, either through successful completion of the file transfer, or by encountering an error in the process.

    But since the focus of the article is transfer of files, I feel reasonably justified in these otherwise unjustifiable shortcuts.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Mike O'Neill

United States United States
Mike O'Neill is a patent attorney in Southern California, where he specializes in computer and software-related patents. He programs as a hobby, and in a vain attempt to keep up with and understand the technology of his clients.

Comments and Discussions

 
QuestionGetFileFromRemoteSender function and SendFileToRemoteRecipient funtion ???membertam789216-Jan-14 17:47 
when did you call GetFileFromRemoteSender function and SendFileToRemoteRecipient funtion ? I downloaded your source code and have some breakpoints on your project but nothing happen
GeneralMy vote of 5memberMember 43208447-May-12 9:35 
Thanks for sharing
GeneralMy vote of 5membermajid hazari29-Jan-11 21:43 
very nice
GeneralCommunication over internetmembernijasec17-May-10 19:36 
Hi, Smile | :)
 
Can you tell me how communication is possible
over internet that is two computer is connected to
internet
poker

Generaltransmit file on the same computer [modified]memberppp50008-Jul-09 0:23 
Mike,
 
I tried to run both exe files to transmit a file on the same PC, but as soon as I clicked "Get file from this location" button, the server stopped listening. Do you have any idea about this matter?
 
I have also configured the windows firewall for allowing your application to run properly.
 
Thanks.
 
modified on Wednesday, July 8, 2009 12:02 PM

General[Message Deleted]memberit.ragester2-Apr-09 21:53 
[Message Deleted]
GeneralTransmitFilememberNovaNuker8-Jul-08 23:51 
What will be the code changes if we decide to use "TransmitFile" API?
GeneralAfxSocketInitmemberkumar_vinit16-Aug-07 2:21 
Hi There,
 
i think AfxSocketInit function also need some discussion .It will help the beginners.
GeneralRe: AfxSocketInitmemberzaodt21-Aug-07 3:01 
Call this function in your CWinApp::InitInstance override to initialize Windows Sockets.
Questioncan u use it with multiple clientsmemberlplover2k9-Jun-07 1:46 
i want to know whether it can used with several clients???
 
and one thing i tried it with a standard sdi application without form view but doesn't seem to work because of the threads... it seems to work only with sdi with formview...
QuestionCan this work on any 2 computer connecting to internetmemberhoanglinh94661-Apr-07 2:06 
Can this work on any 2 computer connecting to internet ??
AnswerRe: Can this work on any 2 computer connecting to internetmemberMike O'Neill1-Apr-07 6:56 
Yes, of course. It was extensively tested under many different connection architectures, ranging from localhost, through LAN, and on to the architecture you are asking about, namely a connection over the Internet.
 
But it works only if both computers are indeed "connected" to the Internet. If there are firewalls, routers etc in the way, then all of these must be configured properly, or else the connection will be blocked.
 
Mike
 

GeneralRe: Can this work on any 2 computer connecting to internetmemberhoanglinh94667-Apr-07 22:07 
I tested this on 2 computer connecting to Internet, but client cannot connect to server via server's IP address(222.254.17.2). 2 computer are using WinXp, how must I configure my firewall and router to use this.
Please help.
 
Linh
GeneralRe: Can this work on any 2 computer connecting to internetmemberMike O'Neill8-Apr-07 7:24 
The problem usually lies in the way that the networks at both computers are configured. The listening network needs special attention, so as to ensure that it is fowarding incoming connection attempts from the share-point (usually a router) to the machine that is listening on PRE_AGREED_PORT.
 
Look at www.portfoward.com[^] for a general discussion of how to configure your network.
 
Also read these questions just below yours:
 
"Problem on shared Internet connection"[^]
 
"Firewall Question"[^]
 
Finally, if you need to configure the router at the listening side, see this other article: "Using UPnP for Programmatic Port Forwardings and NAT Traversal" at http://www.codeproject.com/internet/PortForward.asp[^]
 
Mike

GeneralRe: Can this work on any 2 computer connecting to internetmemberhoanglinh94668-Apr-07 17:06 
Thank you very much
GeneralProblem with Sending Files [modified]memberVichitram8-Feb-07 20:18 
Hi,
I am able to copy the file to the destination Computer. But at the Destination, i am getting the FIle with 0 Bytes. Even after choosing a different File name, I am getting the same result sometimes(like if I am trying to retrieve the File the second time to a different location). Why does this happen?.Frown | :(
 
Can U help me plzzzz.....
 
VichitraBlush | :O
 

-- modified at 3:19 Friday 9th February, 2007
GeneralErron on Client Side in PDAmemberjoyfulljack18-Jul-06 6:54 
A file is created but with 0Bytes. I am sending a file from one PDA to other and i got a error at sending the file size, i dont have the exact error.
 
BYTE* bp = (BYTE*)(&dataLength) + sizeof(dataLength) - cbLeftToReceive;
cbBytesRet = sockClient.Receive( bp, cbLeftToReceive );

// test for errors and get out if they occurred
if ( cbBytesRet == SOCKET_ERROR || cbBytesRet == 0 )
{
int iErr = ::GetLastError();
MessageBox(TEXT("Error2"),MB_OK);
/* you should handle the error here */

bRet = FALSE;
goto PreReturnCleanup;
}
 
Is there a way i can use something instead of "TRACE" can you correct this cide plz.
 
Krishna
GeneralRe: Erron on Client Side in PDAmemberMike O'Neill18-Jul-06 7:43 
Instead of displaying a message box with "Error2" in it (which is meaningless), display the information that was contained in the original TRACE statement. In particular, display the values of cbBytesRet and iErr, which together will tell you exactly what happened and what went wrong.
 
See http://msdn2.microsoft.com/en-us/library/ct7d990b.aspx[^] which will tell you how to interpret the values for cbBytesRet and iErr.
 
Best,
Mike
QuestionHow to add the limit of upper velocity?memberextraf1-Jun-06 19:52 
rt
Like eMule and other download tool which can limit the upper velocity like 600kb/b, Can I add this feature to this software?
QuestionHow to add multithread support?memberAmeSagit30-May-06 10:09 
As I am a beginner on multithreading and MFC's CSocket,I am puzzled how to add multithread support for CSocket.
The project I'm doing now is design a file transport that support multithreading,and it is implemented by CSocket.
Do you have any suggests?
Thank you very much.
Generalclient/server can both send a filememberbreakpoint28-Mar-06 21:42 
I am wondering if sending/receiving file at the same time from both client and server possible by adding both the functions GetFileFromRemoteSender() and SendFileToRemoteRecipient() to client and server.
 
Good article on networking.
 
"We don't see things how they are. We see things as we are." -Talmud
GeneralGetFileEventmembermambohoe8126-Jan-06 4:28 
How do you derive at the numbers for this:
 
const UINT UWM_GETFILEEVENT = ::RegisterWindowMessage(
_T( "UWM_GETFILEEVENT_F6A100CA_692D_478d_B28C_8E87A1991EA1" ) );
 
& similarly for the server side. Reason is cos i tried using the same values as yours but my status text is not getting updated so i supposed the events are not working out well.
QuestionHow to get Client IP (LAN)memberDivya Rathore11-Jan-06 7:44 
Could I get the IP address of a client connected over Local Area Network? Am a newbie in network programming.. hence the Q may be too basic.
 
regards,
- D
AnswerRe: How to get Client IP (LAN)memberMorar Sebastian4-May-06 9:41 
GetPeerName(szIP,nPort);
GeneralProblems executing the programmemberElaine Loo28-Dec-05 21:29 
Hi all,
 
I have tried your program without the mismatches but i am unable to open the .exe in the debug and release folder when i used in on a pc without the visual c++.net application.
 
When i used your program, i can open the .exe in the release folder but i cannot open the .exe in the debug folder.
 
There is an error message saying "Application failed to start because MFC71D.DLL was not found. Reinstalling the application may fix this problem".
 
Can anyone help me with this problem? Thank you.
 
Best Regards,
Elaine

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

| Advertise | Privacy | Mobile
Web01 | 2.8.141022.2 | Last Updated 1 Nov 2004
Article Copyright 2004 by Mike O'Neill
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid