Sample code for 30+ languages & platforms
PureBasic

Transfer a File using Sockets (TLS or non-TLS)

See more Socket/SSL/TLS Examples

Demonstrates how to two programs, one a socket writer and the other a socket reader, can transfer a file. The connection can be TLS or a regular non-encrypted TCP connection.

Chilkat PureBasic Downloads

PureBasic
IncludeFile "CkBinData.pb"
IncludeFile "CkSocket.pb"

Procedure ChilkatExample()

    success.i = 0

    ; This example requires the Chilkat API to have been previously unlocked.
    ; See Global Unlock Sample for sample code.

    ; On the sending side, we'll load the file into a BinData object and send.
    ; On the receiving side, we'll read from the socket connection into a BinData, and save to a file.
    ; This example assumes the file is not crazy-large, and that the entire contents
    ; can fit into memory.  
    ; (If the file is too large for memory, there are other ways to send. It just involves streaming or 
    ; sending the file chunk-by-chunk..)

    ; This section of code is for the sender.
    bdToSend.i = CkBinData::ckCreate()
    If bdToSend.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    success = CkBinData::ckLoadFile(bdToSend,"somePath/someFile.dat")
    ; Assume success for the example...

    sndSock.i = CkSocket::ckCreate()
    If sndSock.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    bUseTls.i = 1
    port.i = 5555
    maxWaitMs.i = 5000
    success = CkSocket::ckConnect(sndSock,"some_domain_or_ip.com",port,bUseTls,maxWaitMs)
    ; Assume success for the example...

    ; Tell the receiver how many bytes are coming.
    numBytes.i = CkBinData::ckNumBytes(bdToSend)
    bBigEndian.i = 1
    success = CkSocket::ckSendInt32(sndSock,numBytes,bBigEndian)

    ; Send the file data (sends the entire contents of bdToSend).
    success = CkSocket::ckSendBd(sndSock,bdToSend,0,0)

    ; Get an acknowledgement.
    success = CkSocket::ckReceiveInt32(sndSock,bBigEndian)
    If success = 0
        Debug CkSocket::ckLastErrorText(sndSock)
        CkBinData::ckDispose(bdToSend)
        CkSocket::ckDispose(sndSock)
        ProcedureReturn
    EndIf

    ; Did the receiver get the correct number of bytes?
    If CkSocket::ckReceivedInt(sndSock) <> numBytes
        Debug "The receiver did not acknowledge with the correct number of bytes."
        CkBinData::ckDispose(bdToSend)
        CkSocket::ckDispose(sndSock)
        ProcedureReturn
    EndIf

    Debug "File sent!"

    ; ------------------------------------------------------------------------------------
    ; The code below is for the receiving side (running on some other computer..)

    listenSock.i = CkSocket::ckCreate()
    If listenSock.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    success = CkSocket::ckBindAndListen(listenSock,5555,25)
    If success = 0
        Debug CkSocket::ckLastErrorText(listenSock)
        CkBinData::ckDispose(bdToSend)
        CkSocket::ckDispose(sndSock)
        CkSocket::ckDispose(listenSock)
        ProcedureReturn
    EndIf

    ; Get the next incoming connection
    ; Wait a maximum of 20 seconds (20000 millisec)
    rcvSock.i = CkSocket::ckCreate()
    If rcvSock.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    success = CkSocket::ckAcceptNext(listenSock,20000,rcvSock)
    If success = 0
        Debug CkSocket::ckLastErrorText(listenSock)
        CkBinData::ckDispose(bdToSend)
        CkSocket::ckDispose(sndSock)
        CkSocket::ckDispose(listenSock)
        CkSocket::ckDispose(rcvSock)
        ProcedureReturn
    EndIf

    ; The sender will first send the big-endian integer for the number of bytes
    ; that are forthcoming..
    success = CkSocket::ckReceiveInt32(rcvSock,bBigEndian)
    If success <> 1
        Debug CkSocket::ckLastErrorText(rcvSock)
        CkBinData::ckDispose(bdToSend)
        CkSocket::ckDispose(sndSock)
        CkSocket::ckDispose(listenSock)
        CkSocket::ckDispose(rcvSock)
        ProcedureReturn
    EndIf

    numBytesComing.i = CkSocket::ckReceivedInt(rcvSock)

    ; Receive that many bytes..
    bdReceived.i = CkBinData::ckCreate()
    If bdReceived.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    success = CkSocket::ckReceiveBdN(rcvSock,numBytesComing,bdReceived)
    If success <> 1
        Debug CkSocket::ckLastErrorText(rcvSock)
        CkBinData::ckDispose(bdToSend)
        CkSocket::ckDispose(sndSock)
        CkSocket::ckDispose(listenSock)
        CkSocket::ckDispose(rcvSock)
        CkBinData::ckDispose(bdReceived)
        ProcedureReturn
    EndIf

    ; Acknowledge the sender by sending back the number of bytes we received.
    success = CkSocket::ckSendInt32(rcvSock,CkBinData::ckNumBytes(bdReceived),bBigEndian)

    ; Close the connection.
    maxWaitMs.i = 20
    CkSocket::ckClose(rcvSock,maxWaitMs)

    ; Save the received data to a file.
    success = CkBinData::ckWriteFile(bdReceived,"somePath/someFile.dat")
    ; Assume success for the example...

    Debug "File received!"


    CkBinData::ckDispose(bdToSend)
    CkSocket::ckDispose(sndSock)
    CkSocket::ckDispose(listenSock)
    CkSocket::ckDispose(rcvSock)
    CkBinData::ckDispose(bdReceived)


    ProcedureReturn
EndProcedure