Sample code for 30+ languages & platforms
SQL Server

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 SQL Server Downloads

SQL Server
-- Important: See this note about string length limitations for strings returned by sp_OAMethod calls.
--
CREATE PROCEDURE ChilkatSample
AS
BEGIN
    DECLARE @hr int
    DECLARE @iTmp0 int
    -- Important: Do not use nvarchar(max).  See the warning about using nvarchar(max).
    DECLARE @sTmp0 nvarchar(4000)
    DECLARE @success int
    SELECT @success = 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.
    DECLARE @bdToSend int
    EXEC @hr = sp_OACreate 'Chilkat.BinData', @bdToSend OUT
    IF @hr <> 0
    BEGIN
        PRINT 'Failed to create ActiveX component'
        RETURN
    END

    EXEC sp_OAMethod @bdToSend, 'LoadFile', @success OUT, 'somePath/someFile.dat'
    -- Assume success for the example...

    DECLARE @sndSock int
    EXEC @hr = sp_OACreate 'Chilkat.Socket', @sndSock OUT

    DECLARE @bUseTls int
    SELECT @bUseTls = 1
    DECLARE @port int
    SELECT @port = 5555
    DECLARE @maxWaitMs int
    SELECT @maxWaitMs = 5000
    EXEC sp_OAMethod @sndSock, 'Connect', @success OUT, 'some_domain_or_ip.com', @port, @bUseTls, @maxWaitMs
    -- Assume success for the example...

    -- Tell the receiver how many bytes are coming.
    DECLARE @numBytes int
    EXEC sp_OAGetProperty @bdToSend, 'NumBytes', @numBytes OUT
    DECLARE @bBigEndian int
    SELECT @bBigEndian = 1
    EXEC sp_OAMethod @sndSock, 'SendInt32', @success OUT, @numBytes, @bBigEndian

    -- Send the file data (sends the entire contents of bdToSend).
    EXEC sp_OAMethod @sndSock, 'SendBd', @success OUT, @bdToSend, 0, 0

    -- Get an acknowledgement.
    EXEC sp_OAMethod @sndSock, 'ReceiveInt32', @success OUT, @bBigEndian
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @sndSock, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @bdToSend
        EXEC @hr = sp_OADestroy @sndSock
        RETURN
      END

    -- Did the receiver get the correct number of bytes?
    EXEC sp_OAGetProperty @sndSock, 'ReceivedInt', @iTmp0 OUT
    IF @iTmp0 <> @numBytes
      BEGIN

        PRINT 'The receiver did not acknowledge with the correct number of bytes.'
        EXEC @hr = sp_OADestroy @bdToSend
        EXEC @hr = sp_OADestroy @sndSock
        RETURN
      END


    PRINT 'File sent!'

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

    DECLARE @listenSock int
    EXEC @hr = sp_OACreate 'Chilkat.Socket', @listenSock OUT

    EXEC sp_OAMethod @listenSock, 'BindAndListen', @success OUT, 5555, 25
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @listenSock, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @bdToSend
        EXEC @hr = sp_OADestroy @sndSock
        EXEC @hr = sp_OADestroy @listenSock
        RETURN
      END

    -- Get the next incoming connection
    -- Wait a maximum of 20 seconds (20000 millisec)
    DECLARE @rcvSock int
    EXEC @hr = sp_OACreate 'Chilkat.Socket', @rcvSock OUT

    EXEC sp_OAMethod @listenSock, 'AcceptNext', @success OUT, 20000, @rcvSock
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @listenSock, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @bdToSend
        EXEC @hr = sp_OADestroy @sndSock
        EXEC @hr = sp_OADestroy @listenSock
        EXEC @hr = sp_OADestroy @rcvSock
        RETURN
      END

    -- The sender will first send the big-endian integer for the number of bytes
    -- that are forthcoming..
    EXEC sp_OAMethod @rcvSock, 'ReceiveInt32', @success OUT, @bBigEndian
    IF @success <> 1
      BEGIN
        EXEC sp_OAGetProperty @rcvSock, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @bdToSend
        EXEC @hr = sp_OADestroy @sndSock
        EXEC @hr = sp_OADestroy @listenSock
        EXEC @hr = sp_OADestroy @rcvSock
        RETURN
      END

    DECLARE @numBytesComing int
    EXEC sp_OAGetProperty @rcvSock, 'ReceivedInt', @numBytesComing OUT

    -- Receive that many bytes..
    DECLARE @bdReceived int
    EXEC @hr = sp_OACreate 'Chilkat.BinData', @bdReceived OUT

    EXEC sp_OAMethod @rcvSock, 'ReceiveBdN', @success OUT, @numBytesComing, @bdReceived
    IF @success <> 1
      BEGIN
        EXEC sp_OAGetProperty @rcvSock, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @bdToSend
        EXEC @hr = sp_OADestroy @sndSock
        EXEC @hr = sp_OADestroy @listenSock
        EXEC @hr = sp_OADestroy @rcvSock
        EXEC @hr = sp_OADestroy @bdReceived
        RETURN
      END

    -- Acknowledge the sender by sending back the number of bytes we received.
    EXEC sp_OAGetProperty @bdReceived, 'NumBytes', @iTmp0 OUT
    EXEC sp_OAMethod @rcvSock, 'SendInt32', @success OUT, @iTmp0, @bBigEndian

    -- Close the connection.
    DECLARE @maxWaitMs int
    SELECT @maxWaitMs = 20
    EXEC sp_OAMethod @rcvSock, 'Close', @success OUT, @maxWaitMs

    -- Save the received data to a file.
    EXEC sp_OAMethod @bdReceived, 'WriteFile', @success OUT, 'somePath/someFile.dat'
    -- Assume success for the example...


    PRINT 'File received!'

    EXEC @hr = sp_OADestroy @bdToSend
    EXEC @hr = sp_OADestroy @sndSock
    EXEC @hr = sp_OADestroy @listenSock
    EXEC @hr = sp_OADestroy @rcvSock
    EXEC @hr = sp_OADestroy @bdReceived


END
GO