A proxy like phConnector etc. usually has three sockets (i.e. network connections):
One socket connects to the
GatewayServer (aka 'Login Server') and later it disconnects from the GatewayServer and can be reused to connect to the
AgentServer (aka. 'Game Server').
The second socket is a server socket, usually listening on port 15779 and hostname localhost.
This is the port that the client connects to.
The last socket is also a server socket, which listens on a user-defined port.
The bot, alchemy tool or whatever (just called 'bot' after this) connects to this port. Using specially crafted packets (*) sent to this port, the bot can send packets to the client or the server via the proxy.
A schematic overview:
* Example of a possible header format:
uint16 - total length
uint16 - opcode (real opcode)
byte (bool) - direction flag (00: client, 01: server)
byte[] - data
From this header the proxy can gather all the information needed to send the packet it received from the bot (obviously with the right SRO packet header) to the right socket.
Edit: I just realised that I didn't really answer your question. So, why do we need a proxy? Well, we don't, really. Instead of a proxy we could hook the clients winsock imports and use them directly.
However, this has disadvantages. For example, every bot would need to have its own loader (a proxy can be reused by basically all bots or alchemy tools) to hook the functions, and it wouldn't be possible to host the clients on one PC and run the bots on another.
Edit 2: This post is based on the idea that the proxy and the bot are two separate applications. These days, more advanced bots have a built-in proxy that the client connects to, so only one application is needed.