> For the complete documentation index, see [llms.txt](https://docs.thousandeyes.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.thousandeyes.com/product-documentation/browser-synthetics/transaction-tests/use-cases/api-monitoring/net-module.md).

# Using the net module

When your transaction test script needs to establish a TCP connection with a network target, you'll use the `net` module from ThousandEyes. The ThousandEyes runtime environment for transaction scripts includes the `net` module for creating raw TCP client sockets to servers on arbitrary ports.

## Importing the Module

To use the `net` module, make sure to first import it within your transaction script:

`import net from 'thousandeyes';`

## Creating a Connection

To create a client connection to a remote server, use the `net.connect` function:

`await net.connect(<port>, '<host.ip.address>');`

### DNS Behavior for FQDN Targets

When you pass a fully qualified domain name (FQDN) to `net.connect()`, BrowserBot resolves both A (IPv4) and AAAA (IPv6) records. If either lookup times out, the script can fail during DNS resolution before it attempts the TCP connection. This behavior applies to raw TCP connections from the transaction script and is separate from Chromium page loading.

You can run `dig A <FQDN>` for IPv4 OR `dig AAAA <FQDN>` for IPv6 to check if either of the lookup times out. If either lookup times out, replace the hostname with the known working IP address:

```javascript
const sock = await net.connect(21, '192.0.2.10');
```

Replace `192.0.2.10` with the IP address for your target. This behavior does not mean that every FQDN target must have both A and AAAA records. The failure occurs when a lookup times out.

| Symptom                                                   | Likely cause                                                                                   | Recommended action                                                                    |
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `getaddrinfo EAI_AGAIN` from `net.connect()` with an FQDN | An A (IPv4) or AAAA (IPv6) lookup timed out before the script attempted the raw TCP connection | Use the known working IP address directly, or verify that both lookups return cleanly |
| Direct IP connection works but FQDN connection fails      | DNS resolution fails before the script attempts the raw TCP connection                         | Treat this as a DNS resolution issue, not proof that the TCP service is unavailable   |

If your transaction script fails with `getaddrinfo EAI_AGAIN`, first check whether the script calls `net.connect()` with a hostname. If the target works over IPv4 or IPv6 but the other lookup times out, update the script to use the working IP address instead of the hostname.

## Sending Data

To send data over the socket connection, first assign the result of `net.connect` to a variable:

`let socket = await net.connect(80, '1.1.1.1');`

Then, use the `write` or `writeAll` methods to send data over the socket:

`await socket.writeAll('GET / HTTP/1.1\r\n\r\n');`

To read from the socket, use the `read` or `readAll` methods:

`const response = await socket.readAll();`

#### Example GET Request

In the following example, notice that first the `net` module is imported. Then, after `net.connect` is called, data is sent and received over the socket, using `write` and `read`:

```
import {net} from 'thousandeyes';

runScript();

async function runScript() {
   let host = 'newyork.wan.the-acme-corporation.net';
   let port = 80;
   let requestBody =
`GET / HTTP/1.1
Host: ${host}
User-Agent: thousandeyes-transaction
`

  let client = await net.connect(port, host);
  await client.write(requestBody);
  let response = await client.read();

  console.log(response.toString());
  
};
```

## Advanced Examples

For additional examples, see the [public repository of ThousandEyes transaction scripts](https://github.com/thousandeyes/transaction-scripting-examples/tree/master/API-transaction-scripts).

#### Example: IMAP Login

In the following example, you establish a TCP connection; then send IMAP credentials over the connection you've created:

```
let host = 'box.the-acme-corporation.net';
   let port = 993;
   let imap_password = credentials.get('tonystark@the-acme-corporation.net');

   const sock = await net.connectTls(port, host, {
       minVersion: 'TLSv1.2',
   });

   sock.setEncoding('utf8');

   let imap_commands = [
       `? LOGIN tonystark@the-acme-corporation.net ${imap_password}\n`,
       `? SELECT Inbox\n`,
       `? FETCH 1:1 RFC822\n`,
   ]

   for(var i=0; i < imap_commands.length; i++){
       let command = imap_commands[i];
       await sock.writeAll(command);
     
       // Make driver sleep for .5 seconds
       await driver.sleep(500);
       console.log(command);
       let response = await sock.read();
       console.log(response);
   }
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.thousandeyes.com/product-documentation/browser-synthetics/transaction-tests/use-cases/api-monitoring/net-module.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
