I am not fluent in English, so I’m using a translator. Please bear with me if some of the intended meaning doesn’t come across clearly.
I’m currently working on connecting a Unity TCP client and server using an external IP address obtained from Google Cloud Platform (GCP). However, despite numerous attempts, I am unable to make a successful connection with the fixed IP from GCP. I’m listing below the things I have already checked and the issues that persist. If anyone could point out any overlooked aspects or potential solutions, I would really appreciate it.
I am experiencing issues with a TCP connection in Unity using a static IP created on Google Cloud Platform (GCP). I attempted to establish a server-client connection using TCP with an external IP assigned by GCP, but after multiple tries, I am still unable to resolve the failure described below, and thus unable to use the external IP. If anyone has suggestions on what I might have overlooked, or if you have potential solutions or insights on the cause, I would greatly appreciate your help.
Confirmed Functional Components
Internal IP Address Port Forwarding: Verified NAT settings by logging into the router. Ping Test: Confirmed active network connection by pinging the GCP server’s IP from the client.
GCP Firewall Rules: Source IP Range: 0.0.0.0/0 TCP Protocol: Allowed Direction: Ingress Port and Static IP: No issues identified.
VM Instance Settings: Firewall: HTTP and HTTPS traffic allowed.
GCP SSH Remote Server Access: Successfully logged into the server with the static IP created by GCP.
Local Testing with 127.0.0.1: Local testing was successful.
Issues: Unity Error: Result: Unable to connect due to the target computer actively refusing the connection.
Attempts to Disable Windows Firewall: Tried disabling Windows Firewall but encountered the same failure. Client Code Execution Delay: Delayed client code execution by 5 seconds to ensure the server starts first, but no change in outcome.
Unity Source Code Setup: The server and client codes were assigned to separate components on empty GameObjects in Unity.
Server.cs
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using UnityEngine;
using System;
using System.IO;
public class Server : MonoBehaviour
{
List<ServerClient> clients;
List<ServerClient> disconnectList;
TcpListener server;
bool serverStarted;
private const int PORT = 8000; // Set port number
private const string IP_ADDRESS = "0.0.0.0"; // Allow connections from all IPs
public void ServerCreate()
{
clients = new List<ServerClient>();
disconnectList = new List<ServerClient>();
try
{
server = new TcpListener(IPAddress.Parse(IP_ADDRESS), PORT);
server.Start();
Debug.Log($"Server started on port {PORT}.");
StartListening();
serverStarted = true;
}
catch (Exception e)
{
Debug.LogException(e);
}
}
void Start()
{
ServerCreate();
}
void Update()
{
if (!serverStarted) return;
foreach (ServerClient c in clients)
{
if (!IsConnected(c.tcp))
{
c.tcp.Close();
disconnectList.Add(c);
continue;
}
else
{
NetworkStream s = c.tcp.GetStream();
if (s.DataAvailable)
{
string data = new StreamReader(s, true).ReadLine();
if (data != null)
OnIncomingData(c, data);
}
}
}
for (int i = 0; i < disconnectList.Count; i++)
{
Debug.Log($"{disconnectList[i].clientName} disconnected.");
clients.Remove(disconnectList[i]);
disconnectList.RemoveAt(i);
}
}
bool IsConnected(TcpClient c)
{
try
{
if (c != null && c.Client != null && c.Client.Connected)
{
if (c.Client.Poll(0, SelectMode.SelectRead))
return !(c.Client.Receive(new byte[1], SocketFlags.Peek) == 0);
return true;
}
else
return false;
}
catch
{
return false;
}
}
void StartListening()
{
server.BeginAcceptTcpClient(AcceptTcpClient, server);
}
void AcceptTcpClient(IAsyncResult ar)
{
TcpListener listener = (TcpListener)ar.AsyncState;
ServerClient newClient = new ServerClient(listener.EndAcceptTcpClient(ar));
clients.Add(newClient);
Debug.Log($"Client connected: {newClient.clientName}");
StartListening();
}
void OnIncomingData(ServerClient c, string data)
{
if (data.Contains("&NAME"))
{
c.clientName = data.Split('|')[1];
Debug.Log($"{c.clientName} connected.");
return;
}
}
public void Broadcast(string data, List<ServerClient> cl)
{
foreach (var c in cl)
{
try
{
StreamWriter writer = new StreamWriter(c.tcp.GetStream());
writer.WriteLine(data);
writer.Flush();
}
catch (Exception e)
{
Debug.LogException(e);
}
}
}
}
public class ServerClient
{
public TcpClient tcp;
public string clientName;
public ServerClient(TcpClient clientSocket)
{
clientName = "Guest";
tcp = clientSocket;
}
}
Client.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using System.IO;
using System;
public class Client : MonoBehaviour
{
bool socketReady;
TcpClient socket;
NetworkStream stream;
StreamWriter writer;
StreamReader reader;
private const string SERVER_IP = "34.64.217.7"; // GCP Static IP
private const int SERVER_PORT = 8000; // Client port number
public void ConnectToServer()
{
if (socketReady) return;
try
{
socket = new TcpClient(SERVER_IP, SERVER_PORT);
stream = socket.GetStream();
writer = new StreamWriter(stream);
reader = new StreamReader(stream);
socketReady = true;
Debug.Log("Connected to server.");
SendClientName("Guest" + UnityEngine.Random.Range(1000, 10000)); // Random client name
}
catch (Exception e)
{
Debug.Log($"Socket error: {e.Message}");
}
}
void Start()
{
StartCoroutine(ConnectAfterDelay());
}
private IEnumerator ConnectAfterDelay()
{
yield return new WaitForSeconds(5); // Delay to allow server startup
ConnectToServer();
}
void Update()
{
if (socketReady && stream.DataAvailable)
{
string data = reader.ReadLine();
if (data != null)
Debug.Log(data); // Display received data
}
}
void SendClientName(string clientName)
{
Send($"&NAME|{clientName}");
}
void Send(string data)
{
if (!socketReady) return;
writer.WriteLine(data);
writer.Flush();
}
void OnApplicationQuit()
{
CloseSocket();
}
void CloseSocket()
{
if (!socketReady) return;
writer.Close();
reader.Close();
socket.Close();
socketReady = false;
}
}
Hi @AI-AM,
Welcome to Google Cloud Community!
Ensure that your firewall rule and VM instance are using the same network tags. Additionally, verify that the TCP port specified in the firewall rule matches the port being used by both the server and client applications.
Example of firewall rule:
Example of instance:
If the issue is not resolved, it is recommended to contact Google Cloud Support. When contacting them, provide comprehensive details and include screenshots.
I hope the above information is helpful.