Bueno... yo lo hago de la siguiente manera.
1-. Tengo mi servidor.
2-. Los clientes se conectan al servidor, y mandan un mensaje para registrarse, por ejemplo en XML (Si no mandan este mensaje, el socket estará conectado, pero LA APLICACIÓN no sabrá como identificar un socket de otro.
2.1-. Al mandar el mensaje, asocio, por ejemplo, en una hashtable, el nombre del usuario, junto con su socket. Asi, cuando queira mandar algo, mando el nombre del usuario y el msanje a un método, este método recorrerá el hashtable, hasta encontrar el nombre de usuairo y entonces usará ese socket para mandar el mensaje.
¿Me expliqué?
Te muestro un pequeño ejemplo de mi código, en este caso, en vez de usar un hashtable, use una List<T> con una clase mia.
Código:
//El txtEmail, es lo que uso para recoger el socket específico de entre todos los que están conectados a mi servidor.
public void EnviarDatosCliente(string txtEmail, string txtMensaje)
{
ClsSocket objCliente = (from cliente in listaSockets where cliente.DireccionEmail == txtEmail select cliente).First<ClsSocket>();
byte[] bytesMensaje = Encoding.UTF8.GetBytes(txtMensaje);
EnviarDatos(objCliente.ObjSocket, bytesMensaje);
}
private void EnviarDatos(Socket objSocket, byte[] bytesMensaje)
{
objSocket.BeginSend(bytesMensaje, 0, bytesMensaje.Length, SocketFlags.None, new AsyncCallback(DatosEnviadosAr), new Object[] { objSocket, bytesMensaje });
}