Class

TCPSocket


Description

Used for TCP/IP communication. For secure communications, use SSLSocket instead.

Methods

Name

Parameters

Returns

Shared

Close

Connect

Disconnect

EndOfFile

Boolean

Flush

Listen

Lookahead

encoding As TextEncoding = Nil

String

Poll

Purge

Read

byteCount As Integer, encoding As TextEncoding = Nil

String

ReadAll

encoding As TextEncoding = Nil

String

ReadError

Boolean

Write

Text As String

WriteError

Boolean

Events

Name

Parameters

Returns

Connected

DataAvailable

Error

e As RuntimeException

SendComplete

UserAborted As Boolean

SendProgress

bytesSent As Integer, bytesLeft As Integer

Boolean

Property descriptions


TCPSocket.Address

Address As String

The TCP/IP address to try to connect to.

In this example, the address has been entered into a TextField.

TCPSocket1.Address = TextField1.Text

TCPSocket.BytesAvailable

BytesAvailable As Integer

The number of bytes of data are available in the internal receive buffer.

This property is read-only.

TextField1.Text = Me.BytesAvailable.ToString

TCPSocket.BytesLeftToSend

BytesLeftToSend As Integer

The number of bytes left in the queue remaining to be sent.

This property is read-only.

This enables you to create a synchronous socket without needing to subclass it.

TextField1.Text = Me.BytesLeftToSend.ToString

TCPSocket.Handle

Handle As Integer

This is the socket's internal descriptor and it can be used with Declare statements.

This property is read-only.

  • On Windows, Handle is a Socket, suitable for use in Declares on Windows.

  • On macOS and Linux, Handle is a UNIX socket descriptor.

The descriptor is platform-specific. If Handle is less than zero, the descriptor is not available.


TCPSocket.IsConnected

IsConnected As Boolean

Indicates whether the socket is currently connected.

This property is read-only.

For TCPSocket, a connection means you can send and receive data and are connected to a remote machine. For UDPSockets, this means that you are bound to the port and are able to send, receive, join or leave multicast groups, or set socket options.

If EasyUDPSocket1.IsConnected Then
  ' proceed using the connection
Else
  MessageBox("Connection failed!")
End If

TCPSocket.LocalAddress

LocalAddress As String

The local IP address of the computer.

This property is read-only.

Var localIP As String = Socket1.LocalAddress

TCPSocket.NetworkInterface

NetworkInterface As NetworkInterface

Specifies which network interface the socket should use when binding.

You can get the network interface(s) of the user's computer by calling the GetNetworkInterface method of the System module.

Leaving this property set to Nil will use the currently selected interface. In the case of UDPSockets, if you assign a non-Nil value, the socket may not be able to receive broadcast messages. The behavior is OS-dependent; it appears to work on Windows but not on other supported operating systems. If you wish to send broadcast packets out, then you should not bind to a specific interface because the behavior is undefined.

This example specifies that the TCPSocket will use the first Network Interface on the user's computer.

TCPSocket1.NetworkInterface = System.NetworkInterface(0)

TCPSocket.Port

Port As Integer

The port to bind on or connect to.

On most operating systems, attempting to bind to a port less than 1024 causes a Error event to fire with an error number 107 unless the application is running with administrative permissions. This is due to security features built into the underlying OS.

You need to set the port property explicitly before any call to Listen or Connect as the Port property will be modified to reflect what the actual bound port is during the various stages of operation.

For instance, if you listen on port 8080 and a connection comes in, you can check the Port property to ensure that you're still listening on port 8080 (that the port hasn't been hijacked). Or, if you connect to a socket on port 8080, once the connection occurs, you can check to see what port the OS has bound you to. This will be a random-seeming port number.

This trick can be very useful when you do things like Listen on port 0. In that case, the OS will pick a port for you and listen on it. Then you can check the Port property to see which port the OS picked. This functionality is used for various protocols, such as FTP.

This example sets the Port to 8080.

TCPSocket1.Port = 8080

TCPSocket.RemoteAddress

RemoteAddress As String

The address of the remote machine you are connected to.

This property is read-only.

Use this instead of the Address property to determine the address of the machine you are actually connected to.

This example reports the address of the remote machine that the user is connected to. It is in the Connected event.

TextField1.Text = Me.RemoteAddress

Method descriptions


TCPSocket.Close

Close

Closes the socket's connection, closes any connections the socket may have, and resets the socket.

The only information that is retained after calling Close is the socket's port, address (in the case of TCPSocket), and data left in the socket's receive buffer. All other information is discarded.

This example closes the EasyTCPSockets that were open. The sockets were added to the main window.

Connector.Close
Listener.Close

TCPSocket.Connect

Connect

Attempts to connect.

For TCPSocket, the address and port properties must be set. For UDPSockets, the port property must be set. The Connect method binds a socket to a port. After calling Connect, the Port property will report the actual port you are bound to.


TCPSocket.Disconnect

Disconnect

Disconnects the socket, resets it, and fires a SocketCore Error event with a 102 error to let you know that the socket has been disconnected.

This example disconnects the EasyTCPSockets that were opened.

Connector.Disconnect
Listener.Disconnect

TCPSocket.EndOfFile

EndOfFile As Boolean

Returns True when there's no more data left to read.

This code reads the rows and columns of data from a tab-delimited text file into a ListBox:

Var f As FolderItem
Var textInput As TextInputStream
Var rowFromFile As String

f = FolderItem.ShowOpenFileDialog("text/plain") ' defined as a FileType
If f <> Nil Then
  textInput = TextInputStream.Open(f)
  textInput.Encoding = Encodings.UTF8

  Do
    rowFromFile = textInput.ReadLine
    Var values() As String = rowFromFile.ToArray(String.Chr(9))
    ListBox1.ColumnCount = values.Count
    ListBox1.AddRow("")
    Var col As Integer
    For Each value As String In values
      ListBox1.CellTextAt(ListBox1.LastAddedRowIndex, col) = value
      col = col + 1
    Next
  Loop Until textInput.EndOfFile

  textInput.Close
End If

This example reads each pair of bytes from a file and writes them in reverse order to a new file. The user chooses the source file using the Open-file dialog box and saves the new file using the Save as dialog box. The EOF property is used to terminate the Do...Loop.

Var readFile As FolderItem = FolderItem.ShowOpenFileDialog("text")
If readFile <> Nil Then
  Var ReadStream As BinaryStream = BinaryStream.Open(readFile, False)
  ReadStream.LittleEndian = True
  Var writeFile As FolderItem = FolderItem.ShowSaveFileDialog("", "")
  If writeFile <> Nil Then
    Var writeStream As BinaryStream = BinaryStream.Create(writeFile, True)
    writeStream.LittleEndian = True
    Do Until ReadStream.EndOfFile
      writeStream.WriteInt8(ReadStream.ReadInt8)
    Loop
    writeStream = Nil
  End If
  readStream = Nil
End If

TCPSocket.Flush

Flush

Immediately sends the contents of internal write buffers to disk or to the output stream.

This function can be useful in point-to-point communication over sockets and similar connections: To optimize for transmission performance, some types of output streams try to collect small pieces of written data into one larger piece for sending instead of sending each piece out individually. By calling Flush, the data collection is stopped and the data is sent without further delay, reducing latency.

When using this on a stream that ends up as a file on disk, it is useful, too: Any short parts of previously written data are written to disk right away, ensuring the data is actually on disk if the application terminates abruptly, e.g. due to a crash.

Avoid calling this method too often. For example, do not call it between successive Write calls because you'll slow down performance without getting much benefit.

A typical use case would look like this:

mySocket.Write("you typed: ")
mySocket.Write(key)
mySocket.Write(".")
mySocket.Flush

TCPSocket.Listen

Listen

Attempts to listen for incoming connections on the currently specified port.

After calling Listen, the Port property will report the actual port you are bound to.


TCPSocket.Lookahead

Lookahead(encoding As TextEncoding = Nil) As String

Returns a String, containing the data that is available in the internal queue without removing it.

The optional Encoding parameter enables you to specify the text encoding of the data to be returned. The default is Nil. Use the Encodings module to specify an encoding.

This example adds the contents of the internal queue to a TextArea. The Listener EasyTCPSocket has been added to the window.

TextArea1.AddText(listener.Lookahead)

TCPSocket.Poll

Poll

Polls the socket manually, which allows a socket to be used synchronously.

The EasyTCPSocket "Listener" has been added to the window.

Listener.Poll

TCPSocket.Purge

Purge

Removes all data from the socket's internal receive buffer. It does not affect the socket's internal send buffer.

Listener.Purge

TCPSocket.Read

Read(byteCount As Integer, encoding As TextEncoding = Nil) As String

Reads byteCount bytes from the input stream and returns a String.

If provided, the optional parameter Enc specifies the text encoding to be defined for the String to be read.

If Count is higher than the amount of bytes currently available in the stream, all available bytes will be returned. Therefore, make sure to always consider the case that you get less than you requested. To see if you received all requested bytes, check the returned string's String property (avoid using Length as it may give a different number if the encoding is not nil).

If not enough memory is available, you get back an empty string.

This example reads the first 1000 bytes from a BinaryStream.

Var readFile As FolderItem = FolderItem.ShowOpenFileDialog("text/plain")
If readFile <> Nil Then
  Var ReadStream As BinaryStream = BinaryStream.Open(readFile, False)
  ReadStream.LittleEndian = True
  TextArea1.Text = ReadStream.Read(1000, Encodings.UTF8)
End If

TCPSocket.ReadAll

ReadAll(encoding As TextEncoding = Nil) As String

Reads all the data from the internal buffer.

This example reads all the data in the buffer into a TextArea.

TextField1.AddText(listener.ReadAll)

TCPSocket.ReadError

ReadError As Boolean

If True then an error occurred during reading.


TCPSocket.Write

Write(Text As String)

Writes the passed text to the output stream.

Note that in order to make sure that the data actually ends up on disk or gets sent to the socket it is connected to, the stream must either get closed or the Flush method be called. Otherwise, the data, if small, may end up temporarily in a write buffer before either a certain time has passed or more data is written. This buffering increases performance when writing lots of small pieces of data, but may be causing unwanted delays when another process, e.g. the other end of a socket connection, is waiting for the data. Consider calling the Flush method to reduce latencies that this buffering may cause in such cases.

If Write fails, an IOException will be raised.

This example displays the Save As dialog box and writes the contents of the TextArea1 to a text file.

Var f As FolderItem
Var stream As BinaryStream
f = FolderItem.ShowSaveFileDialog(FileTypes1.Text, "Untitled.txt")
If f<> Nil Then
  stream = BinaryStream.Create(f, True)
  stream.Write(TextArea1.Text)
  stream.Close
End If

TCPSocket.WriteError

WriteError As Boolean

If True then an error occurred during writing.

Event descriptions


TCPSocket.Connected

Connected

Executes when the connection is established with the server.


TCPSocket.DataAvailable

DataAvailable

Occurs when additional data has come into the internal receive buffer.


TCPSocket.Error

Error(e As RuntimeException)

Occurs when an error occurs with the socket.

These error codes provide you with key information about your socket, and it is not advisable to ignore them.

When an error occurs, the RuntimeException property will likely contain one of the following error codes:

Error Code

Description

0

No error occurred.

100

There was an error opening and initializing the drivers.

101

This error code is no longer used.

102

This code means that you lost your connection.

103

The socket was unable to resolve the address that was specified.

104

This error code is no longer used.

105

The address is currently in use.

106

This is an invalid state error, which means that the socket is not in the proper state to be doing a certain operation.

107

This error means that the port you specified is invalid.

108

This error indicates that your application has run out of memory.

Information on additional error codes is available.

The following example in the Error event handler displays the error code.

MessageBox(Me.e.ErrorNumber.ToString)

TCPSocket.SendComplete

SendComplete(UserAborted As Boolean)

Occurs when a send has completed.

Use this to determine when all your data has been sent. UserAborted will be True if the user aborted the send by returning True from the SendProgress event. You can use this information to update different status variables or to inform user about the success or failure of the transfer. If the send was completed, this value is False. UserAborted will always be False for UDP sockets.


TCPSocket.SendProgress

SendProgress(bytesSent As Integer, bytesLeft As Integer) As Boolean

Occurs when your network provider queues your data in chunks and is about to send the next chunk.

The parameters indicate the amount of progress that has been made during the send. Returns a Boolean.

Returning True from this event causes the send to be cancelled. This does not close the socket's connection; it only clears the buffer. After all of the data has been transferred you will get a final SendProgress event followed by a SendComplete event.

bytesSent is the number of bytes that were sent in the chunk, not the total number of bytes sent.

Interfaces

The TCPSocket class implements the Readable and Writeable class interfaces.

Notes

The Transmission Control Protocol, or TCP, is the basis for most internet traffic. It is a connection-oriented protocol that provides a reliable way to transfer data across a network.

To establish a connection between two computers using TCPSockets, one computer must be set up to listen on a specific port. The other computer (called the client) then attempts to connect by specifying the network address (or IP address) of the remote machine and the port on which to attempt the connection. In order to send and receive data with a remote machine, both machines must have some indication that this connection will be established.That happens by either picking a well-defined port for the listener (or server) to listen on, or by some prior arrangement (e.g., you are the author of both the server and the client program).

When a server receives a connection attempt on the port it is listening on, it accepts the incoming connection, and sends an acknowledgement back to the remote machine. Once both machines have reached an agreement (or are "connected"), then you can begin sending and receiving data. When you close your connection with the remote machine, there is a similar handshake process that goes on, so both computers know that the connection is being terminated.

Because of the amount of error checking and handshakes, TCP is an extremely reliable protocol. When you send a packet of information, it is guaranteed to make it to the remote machine unless you have been disconnected, either abortive or orderly. But this feature comes at the cost of high overhead. A typical TCP packet that is sent over the network has around a 40-byte header that goes with it. This header is checked, and changed by all the various machines en route to its destination. This overhead makes TCP a slower protocol to use. The trade-off is speed versus security, in favor of security. If it is speed you are looking for (for example to support a networked game), then you should look into the UDP protocol.

The TCPSocket handles the disconnection process more gracefully. It tries to do an orderly disconnect when possible (which allows for all data transfers to finish), and will only fall back on an abortive disconnect when it is not possible to do an orderly one. TCPSockets handle flow control, so sending large amount of data will not drop data during the send or the receive process.

It is possible for packets of data to come in before the socket has finished the connection process. If this happens, the TCPSocket is prepared to handle this, so your initial packets will not be lost. This is a Macintosh-only feature; Windows sockets were already prepared to handle these situations.

The SendProgress event allows you to determine send speeds, and tells you how many bytes of data you have sent since your last SendProgress event, as well as how many bytes are left to send. If you return True from the SendProgress event, you cancel the current transfer. This does not close the socket's connection; it only clears the send buffer. You can use this event to determine if a connection is too slow, and cancel it. Once all of the data has been transferred, you will get a last SendProgress event, followed by a SendComplete event.

The RemoteAddress property for a connecting socket returns the IP address of the remote host connection for Windows sockets. One useful thing you can do with the RemoteAddress property is to test to make sure the IP address you wanted to connect to is the same as the IP address you are currently connected to.

TCPSockets can be orphaned. An orphaned socket will keep a lock on itself after you call either the Connect or Listen methods. The socket gets unlocked when it has been disconnected. This means that an orphaned socket will continue to work so long as it is connected. This also means that you need to call the Close method before its lock will be released.

If you orphan a socket, you need to be certain that the socket will get a disconnect message from its connection at some point. For example, some web servers will not release a socket once the data has been transferred to it (for efficiency reasons). When you are done with the socket, it will remain active and connected unless you explicitly call the Close method of the SocketCore class. If you think your socket could be in a state in which it is left open, keep a reference to the socket around somewhere and use the Close method to terminate the connection. Calling the Disconnect method also applies instead of calls to the Close method.

If you use a constructor in a subclass of TCPSocket, you must call the Super class's constructor in your subclass's constructor. The subclass will not work unless this is done.

Binding a TCPSocket to well-known ports below 1024 requires proper privileges on all operating systems.

The TCPSocket class implements the Readable and Writable class interfaces. If you implement either or both of these interfaces, you must provide the methods and parameters specified by these class interfaces.

For more information about class interfaces and how to implement them, see the section "Class Interfaces" in the User's Guide.


Xojo Cloud

Web apps running on Xojo Cloud first have to use the FirewallPort class to open the port used to connect to to TCP externally.

Sample code

This code uses a TCPSocket to establish an internet connection.

Var socket1 As New TCPSocket

' set its port and address
' TextField1 contains a valid url, such as "www.xojo.com"
socket1.Address = "server.domain.com"
socket1.Port = 80

' connect the socket
socket1.Connect

' while the socket isn't connected
While Not socket1.IsConnected
  ' poll the socket to let it do its thing
  socket1.Poll
 ' if an error occurs, the Error event will fire
Wend

' if we broke the loop because we're connected
If socket1.IsConnected Then
  ' here would be a great place to do a synchronous read operation...
  ' if an error occurs, the Error event will fire
End if

' close the socket
socket1.Close

Compatibility

Desktop, console, web and iOS project types on all supported operating systems.

See also

SocketCore parent class; EasyTCPSocket, ServerSocket, SocketCore, SSLSocket, UDPSocket classes; Readable, Writeable class interfaces.