Skip to main content

How to Send a Simple TCP Message (Client) in a Batch Script

Sending a raw TCP message to a listening server is a fundamental networking task. It's the basis for many simple protocols and is essential for tasks like sending data to a log collector, testing if a port is open on a server, or interacting with a simple network service.

However, the native batch scripting environment (cmd.exe) has no built-in command to open a TCP socket and send data. It is a file and process shell, not a networking tool. To accomplish this, you must delegate the task to a more powerful scripting language that is built into Windows: PowerShell.

This guide will teach you the modern and only recommended method for sending a TCP message by using a PowerShell one-liner from within your batch script.

The Challenge: Batch Can't Speak TCP

The cmd.exe interpreter has no commands for creating network sockets, connecting to ports, or writing data streams. Commands like ping use a different protocol (ICMP), and tools like ftp are for a specific, high-level protocol. There is no native netcat or telnet scripting capability. Therefore, a pure-batch solution is not possible.

The best practice is to call PowerShell, which has full access to the .NET framework's powerful networking classes. The System.Net.Sockets.TcpClient class is perfect for this. We can create a one-liner that our batch script can execute to perform the entire operation.

The Core PowerShell Logic Explained

Let's break down the PowerShell one-liner that our batch script will use:

$client = New-Object System.Net.Sockets.TcpClient;
$client.Connect('ServerIP', Port);
$stream = $client.GetStream();
$writer = New-Object System.IO.StreamWriter($stream);
$writer.WriteLine('Your Message');
$writer.Flush();
$stream.Close();
$client.Close();
  1. $client = New-Object ... TcpClient: Creates a new TCP client object.
  2. $client.Connect(...): Attempts to connect to the specified server IP and port. This will fail if nothing is listening.
  3. $stream = $client.GetStream(): Gets the network stream that we can write data to.
  4. $writer = ... StreamWriter(...): Creates a "writer" object that makes it easy to send text.
  5. $writer.WriteLine(...): Sends your message string to the server, followed by a newline character.
  6. $writer.Flush(): Ensures all buffered data is sent immediately.
  7. $stream.Close(); $client.Close();: Properly closes the connection and releases the resources.

The Script: A Simple TCP Message Sender

This batch script acts as a wrapper, executing the PowerShell command to send a message.

@ECHO OFF
SETLOCAL

REM --- Configuration ---
SET "ServerIP=127.0.0.1"
SET "Port=8080"
SET "Message=Hello from the batch script!"

ECHO --- Sending TCP Message ---
ECHO Server: %ServerIP%:%Port%
ECHO Message: "%Message%"
ECHO.

REM --- The PowerShell One-Liner ---
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"$client = New-Object System.Net.Sockets.TcpClient; " ^
"$client.Connect('%ServerIP%', %Port%); " ^
"$stream = $client.GetStream(); " ^
"$writer = New-Object System.IO.StreamWriter($stream); " ^
"$writer.WriteLine('%Message%'); " ^
"$writer.Flush(); " ^
"$stream.Close(); " ^
"$client.Close();"

IF %ERRORLEVEL% EQU 0 (
ECHO [SUCCESS] Message sent successfully.
) ELSE (
ECHO [FAILURE] Failed to send message. Is the server running and the port open?
)

ENDLOCAL
note

The caret (^) is used to break the long PowerShell command across multiple lines for readability.

Common Pitfalls and How to Solve Them

  • "Connection refused": This is the number one cause of failure. It means the Connect() command failed because there was no application listening for connections on the target IP and port.

    • Solution: You must have a server application running and listening on the port before you run your client script. See the practical example below for a simple test server.
  • Firewall Blocking: The connection could be blocked by a firewall on the client machine (outbound) or, more commonly, on the server machine (inbound).

    • Solution: Ensure that the Windows Firewall (or any other firewall) on the server has an inbound rule that allows TCP traffic on the port you are using.
  • Special Characters in the Message: If your message contains single quotes ('), it can break the PowerShell command string.

    • Solution: For complex messages, it's more robust to save the message to a temporary file and have PowerShell read it: $writer.WriteLine((Get-Content 'msg.txt' -Raw)).

Practical Example: Sending a Log to a Simple TCP Server

This example provides both the client batch script and a simple PowerShell listener script so you can test the entire process.

The Server (Listener)

Run this in a PowerShell window first. It will wait for a message.

Listener.ps1
# Listener.ps1
Write-Host "TCP Listener started on port 8080. Waiting for a message..."
$listener = [System.Net.Sockets.TcpListener]::new('0.0.0.0', 8080)
$listener.Start()
$client = $listener.AcceptTcpClient()
$stream = $client.GetStream()
$reader = [System.IO.StreamReader]::new($stream)
$message = $reader.ReadLine()

Write-Host "--- MESSAGE RECEIVED ---"
Write-Host $message
Write-Host "------------------------"

$reader.Close()
$stream.Close()
$client.Close()
$listener.Stop()
Write-Host "Listener stopped."

The Client

Now, run this batch script in a separate cmd.exe window.

Send-Log.bat
@ECHO OFF
SET "LogMessage=CRITICAL: Backup server is offline. - %COMPUTERNAME% at %TIME%"

ECHO Sending log message to the listener...
powershell -Command "$client=New-Object System.Net.Sockets.TcpClient; $client.Connect('127.0.0.1',8080); $stream=$client.GetStream(); $writer=New-Object System.IO.StreamWriter($stream); $writer.WriteLine('%LogMessage%'); $writer.Flush(); $stream.Close(); $client.Close();"

Result

The PowerShell window (running the listener) will immediately display:

--- MESSAGE RECEIVED ---
CRITICAL: Backup server is offline. - MY-PC at 11:30:15.50
------------------------
Listener stopped.

Conclusion

While batch script cannot natively send a TCP message, it can act as a perfect controller for the powerful PowerShell networking engine.

  • The core method is a PowerShell one-liner that uses the System.Net.Sockets.TcpClient class.
  • This hybrid approach is the modern and only recommended method for this task.
  • The most critical prerequisite is that you must have a server application listening on the target IP and port for the connection to succeed.