Hola de nuevo....he estado indagando algo, ya que hace tiempo que no trabajaba con sscanf().
Según el libro de K&R, en las funciones de la familia scanf(), "Un campo de entrada está definido como una cadena de caracteres que no son espacios en blanco;" (un "campo de entrada" es una secuencia del tipo %s, %i, etc).
Pues bien, si cambiamos los caracteres punto y coma que has puesto como separadores por espacios en blanco, funciona perfectamente. Entendemos por espacios en blanco los espacios, nueva línea, tabulador, retorno de carro, etc. Por ejemplo:
void user_serialize (struct user *usr, char *buffer) {
sprintf (buffer, "%s\n%i\n%i", usr->nick, usr->ip, usr->port);
}
void user_unserialize (struct user *usr, char *buffer) {
sscanf (buffer, "%s\n%i\n%i", usr->nick, &usr->ip, &usr->port);
}
El problema lo encontramos si dentro del nick hay un espacio en blanco, ya que scanf detendrá la lectura del primer campo (el nick) cuando encuentre un espacio en blanco. Hay muchas soluciones a este problema. Una de ellas podría ser:
void user_unserialize (struct user *usr, char *buffer) {
char *ptr;
ptr = strchr(buffer, '\n');
strncpy(usr->nick, buffer, ptr-buffer);
sscanf (ptr+1, "%i\n%i", &usr->ip, &usr->port);
}
Lo que hacemos es buscar el primer '\n', y copiamos en el campo nick los caracteres que van desde el comienzo hasta el '\n' (sin incluirlo). Luego, tratamos el buffer con sscanf(), desde la posición siguiente al primer '\n'.
Espero que esto solucione tu problema.
un saludo.