EllanJiang/GameFramework · error · GameFrameworkException
You must connect first.
Error message
You must connect first.
What it means
NetworkChannelBase.Send<T> checks that the channel's underlying Socket exists before enqueueing a packet. If m_Socket is null, the channel has never connected (or Dispose already ran), so GameFramework throws this GameFrameworkException (or fires NetworkChannelError with NetworkErrorCode.SendError if a handler is registered). It guards against sending on a channel with no socket.
Solutions
- Call channel.Connect(ipAddress, port, userData) and wait for the NetworkChannelConnected event before calling Send.
- Check the channel's state (or track connection success) before each Send; skip or queue packets while not connected.
- If the channel was disposed after a disconnect, create/reconnect a new channel via NetworkManager.CreateNetworkChannel instead of reusing the old one.
- Register NetworkChannelError to receive SendError as an event instead of an unhandled exception.
Example fix
// before channel.Send(loginPacket); // throws if never connected // after channel.Connected += (sender, e) => channel.Send(loginPacket); channel.Connect(ipAddress, port, userData);
Defensive patterns
Strategy: validation
Validate before calling
public static bool CanSend(INetworkChannel ch) => ch != null && ch.Id != 0 && IsConnected(ch); // track connection via NetworkChannelConnected/Closed events
Type guard
public static bool IsConnected(INetworkChannel ch) => connectedChannels.Contains(ch);
Try / catch
try { channel.Send(packet); } catch (GameFrameworkException ex) when (ex.Message == "You must connect first.") { QueueForLater(packet); } Prevention
- Only send after the NetworkChannelConnected event fires
- Track channel lifetime; clear references on close/dispose
- Queue outgoing packets while connecting and flush on connect
- Register NetworkChannelError for centralized send-failure handling
When it happens
Trigger: Calling Send<T> on an INetworkChannel obtained from networkManager.GetNetworkChannel/CreateNetworkChannel before ever calling Connect; calling Send after the channel was closed/Disposed (socket set to null); racing a send against channel disposal.
Common situations: Scripts that start sending in Unity Start/Awake before the async Connect completes or on a failed connection; sending after server disconnect handling disposed the channel; forgetting that each channel must be connected individually.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Socket is not active.
- Not supported address family
- Packet is invalid.
- Serialized packet failure.
- Packet header is invalid.
AI-assisted analysis of EllanJiang/GameFramework@d0c010b051 (2026-09-15).
Data as JSON: /api/errors/29c9690bf26beddd.
Report an issue: GitHub.
Appendix: source
Thrown at GameFramework/Network/NetworkManager.NetworkChannelBase.cs:430
}
/// <summary>
/// 向远程主机发送消息包。
/// </summary>
/// <typeparam name="T">消息包类型。</typeparam>
/// <param name="packet">要发送的消息包。</param>
public void Send<T>(T packet) where T : Packet
{
if (m_Socket == null)
{
string errorMessage = "You must connect first.";
if (NetworkChannelError != null)
{
NetworkChannelError(this, NetworkErrorCode.SendError, SocketError.Success, errorMessage);
return;
}
throw new GameFrameworkException(errorMessage);
}
if (!m_Active)
{
string errorMessage = "Socket is not active.";
if (NetworkChannelError != null)
{
NetworkChannelError(this, NetworkErrorCode.SendError, SocketError.Success, errorMessage);
return;
}
throw new GameFrameworkException(errorMessage);
}
if (packet == null)
{
string errorMessage = "Packet is invalid.";
if (NetworkChannelError != null)View on GitHub (pinned to d0c010b051)