Chuleta Cliente + Servidor (2017)

Resumen Español
Universidad Universidad Politécnica de Cataluña (UPC)
Grado Ingeniería de Sistemas de Telecomunicación - 2º curso
Asignatura Sistemes Operatius
Año del apunte 2017
Páginas 2
Fecha de subida 19/06/2017
Descargas 3
Subido por

Vista previa del texto

SERVIDOR 1 El servidor presta los servicios siguientes: 1.Registrar votación. Recibirá del cliente el nombre del partido político y los votos que tiene ese partido. El servidor acumulará los votos a los que tiene ese mismo partido hasta el momento (puede ser que sean los primeros votos para ese partido). El servidor no enviará ningún mensaje de respuesta al cliente.
2.Informar sobre los votos de un partido. Recibirá del cliente el nombre de un partido y responderá con el número de votos acumulados. 3.Informar del ganador. Responderá al cliente con el nombre del partido ganador.
Versión secuencial del servidor typedef struct {char nombre[20];int votos;} Partido; typedef struct { Partido partidos [100]; int num; }ListaPartidos; void AcumularVotos (ListaPartidos *lista, char nombre[20], int votos) {int encontrado =0; int i=0; // Buscamos el partido en la lista while ((i< lista->num) && (encontrado ==0)) if (strcmp(lista->partidos [i].nombre, nombre)==0) encontrado =1; else i=i+1; if (encontrado ==1) // El partido ya está lista->partidos [i].votos = lista->partidos[i].votos + votos; else // el partido no esta y hay que añadirlo al final de la lista {strcpy(lista->partidos [lista->num].nombre, nombre); lista->partidos [lista->num].votos= votos; lista->num = lista->num+1; }} int DameVotos (ListaPartidos *lista, char nombre[20]) {int encontrado =0; int i=0; // Buscamos el partido en la lista while ((i< lista->num) && (encontrado ==0)) if (strcmp(lista->partidos [i].nombre, nombre)==0) encontrado =1; else i=i+1; if (encontrado ==1) // El partido está return lista->partidos [i].votos; else // El partido no está return -1; } char* DameGanador (ListaPartidos *lista) {char ganador[20]; strcpy (ganador, lista->partidos[0].nombre); int votos= lista->partidos[0].votos; int i=1; while (i< lista->num) {if (lista->partidos[i].votos > votos) {strcpy (ganador, lista->partidos[i].nombre); votos= lista->partidos[i].votos; } i=i+1; } return ganador; } void EscribirLista (ListaPartidos *lista) {int i; for (i=0; i<lista->num;i++) printf ("Partido: %s, Votos: %d\n", lista->partidos[i].nombre, lista->partidos[i].votos);} int main(int argc, char *argv[]) { int sock_conn, sock_listen, ret; struct sockaddr_in serv_adr; char buff[512]; char respuesta[512]; ListaPartidos listaPartidos; listaPartidos->num=0; // INICIALITZACIONS// Obrim el socket if ((sock_listen = socket(AF_INET, SOCK_STREAM, 0)) < 0) printf("Error creant socket"); // Fem el bind al port memset(&serv_adr, 0, sizeof(serv_adr));// inicialitza a zero serv_addr serv_adr.sin_family = AF_INET; // asocia el socket a cualquiera de las IP de la máquina.
serv_adr.sin_addr.s_addr = htonl(INADDR_ANY); // escucharemos en el port 9050 serv_adr.sin_port = htons(9050); if (bind(sock_listen, (struct sockaddr *) &serv_adr, sizeof(serv_adr)) < 0) printf ("Error al bind"); //La cola de peticiones pendientes no podrá ser superior a 4 if (listen(sock_listen, 2) < 0) printf("Error en el Listen"); int i; // Atenderemos solo 5 peticione for(;;){ printf ("Escuchando\n"); sock_conn = accept(sock_listen, NULL, NULL); printf ("He recibido conexión\n"); //sock_conn es el socket que usaremos para este cliente // Iniciamos el bucle de atención a este cliente int fin =0; while (fin ==0) { // Esperamos petición de servicío ret=read(sock_conn,buff, sizeof(buff)); buff[ret]='\0'; printf ("Peticion realizada %s\n",buff); // Averiguamos que tipo de petición es char *p = strtok( buff, "/"); int codigo = atoi (p); if (codigo == 1) // acumular votos { // recupero el nombre del partido p = strtok( NULL, "/"); char nombre[20]; strcpy (nombre, p); // recupero los votos p = strtok( NULL, "/"); int votos = atoi (p); // acumulamos votos AcumularVotos (&listaPartidos, nombre, votos); } else if (codigo ==2) //nos piden los votos que lleva un partido { // recupero el nombre del partido p = strtok( NULL, "/"); char nombre[20]; strcpy (nombre, p); int votos = DameVotos (&listaPartidos, nombre); sprintf (respuesta, "2/%d,", votos); write (sock_conn,respuesta, strlen(respuesta)); } else if (codigo ==3) // Nos piden el nombre del ganador {char ganador [20]; strcpy (ganador,DameGanador (&listaPartidos)); sprintf (respuesta, "3/%s,", ganador); printf ("Ganador: %s\n",respuesta); write (sock_conn,respuesta, strlen(respuesta)); } else if (codigo ==0) // desconexión fin =1; } close(sock_conn); } } Versión concurrente (declaraciones) //Variables globales ListaPartidos listaPartidos; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void *AtenderCliente (void *socket) //Función que debe ejecutar el thread {int sock_conn; char buff[512]; char respuesta[512]; int ret; int *s; s = (int *) socket; sock_conn = *s; // Iniciamos el bucle de atenci￳n a este cliente int fin =0; while (fin ==0) {// Esperamos petici￳n de servic■o ret=read(sock_conn,buff, sizeof(buff)); buff[ret]='\0'; printf ("Peticion realizada %s\n",buff); // Averiguamos que tipo de petici￳n es char *p = strtok( buff, "/"); int codigo = atoi (p); if (codigo == 1) // acumular votos {// recupero el nombre del partido p = strtok( NULL, "/"); char nombre[20]; strcpy (nombre, p); // recupero los votos p = strtok( NULL, "/"); int votos = atoi (p); // acumulamos votos pthread_mutex_lock( &mutex ); AcumularVotos (&listaPartidos, nombre, votos); pthread_mutex_unlock( &mutex); } else if (codigo ==2) {…} else if (codigo ==3) {…} else if (codigo ==0) // desconex fin =1; } close(sock_conn); } int main(int argc, char *argv[]) {int sock_conn, sock_listen, ret; struct sockaddr_in serv_adr; listaPartidos.num=0; pthread_t thread[100]; int sockets[100]; // INICIALITZACIONS {…} for(;;){ printf ("Escuchando\n"); sock_conn = accept(sock_listen, NULL, NULL); printf ("He recibido conexi￳n\n"); sockets[i]=sock_conn; pthread_create(&thread[i], NULL, AtenderCliente, &sockets[i]); i=i+1; } } SERVIDOR 2 Inmediatamente después de conectarse, el cliente enviará su nombre que el servidor almacenará en una lista de nombres. Entonces, el cliente puede solicitar al servidor: 1.El nombre del cliente que está guardado en la lista justo en la posición anterior a su nombre. 2.El número de nombres que hay en la lista de nombres.
Versión concurrente typedef char Nombre [20]; typedef struct { int num; Nombre usuarios [100]; } Tlista; int PonNombre (Tlista *l, Nombre usuario) {if (l->num < 100) {strcpy(l->usuarios[l->num], usuario); l->num=l->num+1; return 0; } else return -1; } char *DameAnterior (Tlista *l, Nombre usuario) {Nombre anterior; int encontrado = 0; int i=0; while ((i<l->num) && encontrado ==0) {if (strcmp (l->usuarios[i], usuario) ==0) encontrado=1; else i=i+1; } if ((encontrado ==1)&& (i>0)) strcpy(anterior,l->usuarios[i-1]); else if ((encontrado ==1)&& (i==0)) strcpy( anterior, “Es el primero”); else strcpy( anterior, “No est£”); return anterior; } // Variables globales Tlista conectados; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void *AtenderCliente (void *socket) {Nombre nombre; Nombre anterior; int sock_conn; char buff[512]; char respuesta[512]; int ret; int *s; s = (int *) socket; sock_conn = *s; //Esperamos el nombre que envia el cliente ret=read(sock_conn,nombre, sizeof(nombre)); nombre[ret]='\0'; // Guardamos el nombre en la lista de nombres pthread_mutex_lock( &mutex ); PonConectado (&conectados, nombre); pthread_mutex_unlock( &mutex); // Iniciamos el bucle de atenci￳n a este cliente int fin =0; while (fin ==0) {// Esperamos petici￳n de servic■o ret=read(sock_conn,buff, sizeof(buff)); buff[ret]='\0'; // Averiguamos que tipo de petici￳n es char *p = strtok( buff, "/"); int codigo = atoi (p); if (codigo == 1) // El cliente nos pide el anterior conectado {Nombre anterior; strcpy (anterior, DameAnterior (&conectados, nombre)); sprintf (respuesta, "1/%s,",anterior); write (sock_conn,respuesta, strlen(respuesta)); } else if (codigo ==2) //Nos pide el numero de conectados {sprintf (respuesta, "2/%d,", conectados.num); write (sock_conn,respuesta, strlen(respuesta)); } else if (codigo ==0) // desconexi￳n fin =1; } close(sock_conn); } int main(int argc, char *argv[]) {int sock_conn, sock_listen, ret; struct sockaddr_in serv_adr; pthread_t thread[100]; int sockets[100]; conectados.num=0; // INICIALITZACIONS for(;;){ sock_conn = accept(sock_listen, NULL, NULL); sockets[i]=sock_conn; pthread_create(&thread[i], NULL, AtenderClientes, &sockets[i]); i=i+1; } } SERVIDOR 3 El servidor mantendrá una lista de artículos. Para cada artículo tendremos su nombre y su precio (un entero).
Cualquier cliente, podrá realizar las siguientes peticiones: 1. Desconectarse del servidor 2. Enviar al servidor un nuevo artículo (nombre y precio), que el servidor incorpora a lista 3. Comprar un artículo de la lista. Para ello el cliente enviará al servidor el nombre del artículo y el servidor lo eliminará de la lista. Contestará al cliente informándolo de si ha eliminado correctamente el artículo o si no lo ha podido eliminar porque ya no está en la lista.
En caso de que la lista de artículos sea modificada el servidor enviará automáticamente a todos los clientes conectados un mensaje con el contenido de la lista.
typedef struct { char articulo[20]; int precio; } TProducto; typedef struct { TProducto productos[100]; int num; }TLista; void PonProducto (TLista *lista, char articulo[20], int precio) {strcpy (lista->productos[lista->num].articulo, articulo); lista->productos[lista->num].precio = precio; lista->num= lista->num+1; } int QuitaProducto (TLista *lista, char articulo[20]) //si está elimina y retorna 0, // si no está retorna 1 {int encontrado = 0; int i=0; while (( i<lista->num) && !encontrado) {if (strcmp (lista->productos[i].articulo,articulo)==0) encontrado = 1; else i=i+1; } if (encontrado) {while (i<lista->num-1) {strcpy (lista->productos[i].articulo, lista>productos[i+1].articulo); lista->productos[i].precio = lista->productos[i+1].precio; i=i+1; } lista->num=lista->num-1; return 0; } else return -1; } void DameLista (TLista *lista, char contenido[200]) // genera una frase (que deja en contenido) con el siguiente formato: n/articulo1/precio1/articulo2/precio2 {sprintf (contenido,"%d/",lista->num); int i=0; while (i<lista->num) {sprintf (contenido, "%s%s/%d/",contenido,lista>productos[i].articulo,lista->productos[i].precio); i=i+1; } } //Variables globales TLista listaProductos; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int sockets[100]; int i; void *AtenderCliente (void *socket) {int sock_conn; char buff[512]; char respuesta[512]; int ret; int *s; s = (int *) socket; sock_conn = *s; // Iniciamos el bucle de atencion a este cliente int fin =0; while (fin ==0) {// Esperamos peticion de servicio ret=read(sock_conn,buff, sizeof(buff)); buff[ret]='\0'; printf ("Peticion realizada %s\n",buff); // Averiguamos que tipo de peticion es char *p = strtok( buff, "/"); int codigo = atoi (p); switch case (codigo) case 1: // El cliente envia articulo {// recupero articulo y precio p = strtok( NULL, "/"); char articulo[20]; strcpy (articulo,p); p = strtok( NULL, "/"); int precio; precio=atoi(p); char listado[200]; pthread_mutex_lock( &mutex ); //a?ado articulo a la lista PonProducto(&listaProductos,articulo,precio); //pido el listado para enviarlo a todos DameLista (&listaProductos,listado); pthread_mutex_unlock( &mutex); sprintf (respuesta,"2/%s",listado); int j=0; // Envio listado a todos for (j=0; j<i; j++) write (sockets[j],respuesta, strlen(respuesta)); } break; case 2: // eliminar articulo {// recupero articulo p = strtok( NULL, "/"); char articulo[20]; strcpy (articulo,p); char listado[200]; pthread_mutex_lock( &mutex); // elimino int res = QuitaProducto (&listaProductos,articulo); DameLista (&listaProductos,listado); pthread_mutex_unlock( &mutex); if (res==0) // Ha eliminado el articulo {strcpy (respuesta, "1/0/"); write (sock_conn,respuesta, strlen(respuesta)); //pido el nuevo listado para enviarlo a todos DameLista (&listaProductos,listado); sprintf (respuesta,"2/%s",listado); int j=0; // Envio nuevo a todos for (j=0; j<i; j++) write (sockets[j],respuesta, strlen(respuesta)); } else //no se ha eliminado { strcpy (respuesta, "1/1/"); write (sock_conn,respuesta, strlen(respuesta)); } } break; case 0: //desconexión fin =1; break; } close(sock_conn); } int main(int argc, char *argv[]) {listaProductos.num=0; int sock_conn, sock_listen, ret; struct sockaddr_in serv_adr; primero =0; pthread_t thread[100]; // INICIALITZACIONS for(;;){ sock_conn = accept(sock_listen, NULL, NULL); printf ("He recibido conexi?n\n"); sockets[i]=sock_conn; pthread_create(&thread[i], NULL, AtenderCliente, &sockets[i]); i=i+1; } } SERVIDOR 4 (Cliente con 2 forms) int sockets[10]; int num; void *AtenderCliente (void *socket) {int sock_conn; char buff[512]; char respuesta[512]; int ret; char nombre [20]; int *s; char *p; s = (int *) socket; sock_conn = *s; // Antes de atender al cliente enviamos una notificaci?n indicando cu?ntos conectados hay int i; //Preparo el mensaje que debo enviar a todos sprintf (respuesta, "3/%d,", num); for (i=0; i<num; i++) write (sockets[i], respuesta,strlen(buff2)); int final = 0; // Bucle de espera de petici?n de servicio while (final==0) {// Esperamos petici?n ret=read(sock_conn,buff, sizeof(buff)); buff[ret]='\0'; printf ("Recibo peticion: %s\n", buff); p = strtok (buff, "/"); int cod = atoi (p); if (cod == 1) {// Debo responder con la longitud del nombre // Extraigo el identificador de conversaci?n p = strtok (NULL, "/"); int id = atoi (p); // Extraigo el nombre p = strtok (NULL, "/"); strcpy (nombre, p); // preparo la respuesta sprintf (respuesta, "1/%d/%d,", id,strlen (nombre)); // Y la env?o write (sock_conn,respuesta, strlen(buff2)); } else if (cod ==2) {// Debo responder si el nombre es bonito p = strtok (NULL, "/"); int id = atoi (p); p = strtok (NULL, "/"); strcpy (nombre, p); // Preparo la respuesta if ((nombre[0]== 'M') || (nombre[0] == 'S')) sprintf (respuesta, "2/%d/SI,",id); else {sprintf (respuesta, "2/%d/NO,",id);} // Y la env?o write (sock_conn,respuesta, strlen(buff2)); } else if (cod ==3) {//debo desconectar final = 0; } } close(sock_conn); } int main(int argc, char *argv[]) {int sock_conn, sock_listen, ret; struct sockaddr_in serv_adr; pthread_t thread[10]; // INICIALITZACIONS for(num=0;num<7;num++){ sock_conn = accept(sock_listen, NULL, NULL); sockets[num]=sock_conn; printf ("He recibido conexi?n\n"); pthread_create(&thread[num], NULL, AtenderCliente, &sockets[num]); } printf ("Espero a que acaben los threads\n"); for (num=0; num<7; num++) pthread_join(thread[num],NULL); printf ("Listo\n"); } CLIENTE 2. Servidor 2. Además de atender a las dos peticiones que puede hacer cualquier cliente, cuando un cliente se desconecte el servidor notificará automáticamente a todos los clientes conectados el nombre del cliente que se acaba de desconectar.
public partial class Form1 : Form { delegate void DelegadoParaEscribir(string text); Socket server; Thread atender; public Form1() {InitializeComponent();} private void PonAnterior(string text) {this.anteriorLbl.Text = text;} private void PonConectados(string text) {this.cuantosLbl.Text = text;} private void PonDesconectado(string text) {this.desconectadoLbl.Text = text;} private void atender_mensajes_servidor() {while (true) {int op; byte[] msg = new byte[80]; // recibo mensaje del servidor server.Receive(msg); string mensaje = Encoding.ASCII.GetString(msg); string[] trozos = mensaje.Split('/'); op = Convert.ToInt32(trozos[0]); // Averiguo el tipo de mensaje switch (op) {case 1: //Nombre del anterior anteriorLbl.Invoke(new DelegadoParaEscribir(PonAnterior), new object[] { trozos[1].Split(',')[0] }); break; case 2: //Numero de conectados cuantosLbl.Invoke(new DelegadoParaEscribir(PonConectados), new object[] { trozos[1].Split(',')[0] }); break; case 3: //Nombre del que se acaba de desconectar desconectadoLbl.Invoke(new DelegadoParaEscribir(PonDesconectado), new object[] { trozos[1].Split(',')[0] }); break; } } server.Shutdown(SocketShutdown.Both); server.Close(); this.BackColor = Color.White;} private void Form1_Load(object sender, EventArgs e) {this.BackColor = Color.White;} private void button1_Click(object sender, EventArgs e) {IPAddress direc = IPAddress.Parse(IP.Text); IPEndPoint ipep = new IPEndPoint(direc, 9050); server = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try {server.Connect(ipep);//Intentamos conectar el socket} catch (SocketException ex) {MessageBox.Show("No he podido conectar con el servidor"); return; } this.BackColor = Color.Green; //pongo en marcha el thread ThreadStart ts = delegate { atender_mensajes_servidor(); }; atender = new Thread(ts); atender.Start(); } private void button5_Click(object sender, EventArgs e) {// Enviamos al servidor la petición de desconexión byte[] msg = System.Text.Encoding.ASCII.GetBytes("0/"); server.Send(msg); server.Shutdown(SocketShutdown.Both); server.Close(); this.BackColor = Color.White; atender.Abort(); } private void button2_Click(object sender, EventArgs e) {// Enviamos al servidor el nombre string mensaje = nombreBox.Text; byte[] msg = System.Text.Encoding.ASCII.GetBytes(mensaje); server.Send(msg); nombreBox.Text = null; } private void button4_Click(object sender, EventArgs e) {// Pedimos al servidor el anterior conectado byte[] msg = System.Text.Encoding.ASCII.GetBytes("1/"); server.Send(msg); } private void button3_Click(object sender, EventArgs e) {// Pedimos al servidor el numero de conectados byte[] msg = System.Text.Encoding.ASCII.GetBytes("2/"); server.Send(msg); } } } CLIENTE. Cuando un cliente da por finalizada la frase que están construyendo entre todos, el servidor envía la frase terminada a todos los clientes conectados de forma automática sin que los clientes tengan que solicitarla. Además, se incorpora un servicio nuevo que permite a cualquier cliente solicitar al servidor la última palabra que se incorporó a la frase.
public partial class Form1 : Form {delegate void DelegadoParaEscribir(string text); Socket server; Thread atender; public Form1(){InitializeComponent(); } private void PonFrase(string text) { this.fraseLbl.Text = text; } private void PonPalabra(string text) {this.palabraLbl.Text = text;} private void atender_mensajes_servidor() {//igual que antes switch (op){ case 0: //El servidor envia la frase fraseLbl.Invoke(new DelegadoParaEscribir(PonFrase), new object[] { trozos[1].Split(',')[0] }); break; case 1: //El servidor envia la ultima palabra fraseLbl.Invoke(new DelegadoParaEscribir(PonPalabra), new object[] { trozos[1].Split(',')[0] }); break; } } server.Shutdown(SocketShutdown.Both); server.Close(); this.BackColor = Color.White; } private void Form1_Load(object sender, EventArgs e) {…} private void button1_Click(object sender, EventArgs e) {…} private void button5_Click(object sender, EventArgs e) {…} private void button2_Click(object sender, EventArgs e) {//envía palabra string mensaje = "1/"+palabraBox.Text; byte[] msg = System.Text.Encoding.ASCII.GetBytes(mensaje); server.Send(msg); palabraBox.Text = null; } private void button4_Click(object sender, EventArgs e) {// Enviamos al servidor la petición de acabar frase byte[] msg = System.Text.Encoding.ASCII.GetBytes("2/"); server.Send(msg); } private void button3_Click(object sender, EventArgs e) {// Enviamos al servidor la petición de ultima palabra enviada byte[] msg = System.Text.Encoding.ASCII.GetBytes("3/"); server.Send(msg); } } } CLIENTE SERVIDOR 3 public partial class Form1 : Form {delegate void DelegadoParaEscribir(string text); delegate void DelegadoParaActualizarLista(string[] trozos); delegate void DelegadoParaBorrar(); Socket server; Thread atender; int coste; //precio del articulo seleccionado public Form1() {InitializeComponent(); CheckForIllegalCrossThreadCalls = false; //Necesario para que los elementos de los formularios puedan ser accedidos desde threads diferentes a los que los crearon } private void Borrar() {this.compraBox.Text = null;} private void ActualizaDisponible(string text) {this.disponibleBox.Text = text;} private void ActualizaGrid(string[] trozos) {int k=2; int n = Convert.ToInt32(trozos[1]); articulosGrid.RowCount=n; for (int i = 0; i < n; i++) {articulosGrid.Rows[i].Cells[0].Value = trozos[k]; articulosGrid.Rows[i].Cells[1].Value = trozos[k + 1]; k = k + 2; } } private void atender_mensajes_servidor() {//lo mismo de antes switch (op) {case 1: //Respuesta a la compra if (trozos[1] == "0") {MessageBox.Show("Compra efectuada con éxito"); int d = Convert.ToInt32(disponibleBox.Text); d = d - coste; disponibleBox.Invoke(new DelegadoParaEscribir(ActualizaDisponible), new object[] { d.ToString() }); compraBox.Invoke(new DelegadoParaBorrar(Borrar)); } else {MessageBox.Show("Llegaste tarde"); compraBox.Invoke(new DelegadoParaBorrar(Borrar)); } break; case 2: //Lista de articulos articulosGrid.Invoke(new DelegadoParaActualizarLista(ActualizaGrid), new object[] { trozos }); break; } } } private void Form1_Load(object sender, EventArgs e) {…} private void button1_Click(object sender, EventArgs e) {…} private void button5_Click(object sender, EventArgs e) {…} private void button4_Click(object sender, EventArgs e) {// Enviamos un articulo nuevo byte[] msg = System.Text.Encoding.ASCII.GetBytes("1/"+nombreBox.Text+" /"+precioBox.Text); server.Send(msg); nombreBox.Text = null; precioBox.Text = null; } private void button3_Click(object sender, EventArgs e) {// Intentamos comprar el articulo seleccionado if (compraBox.Text == null) MessageBox.Show("Primero clica un articulo en la lista"); else {byte[] msg = System.Text.Encoding.ASCII.GetBytes("2/" + compraBox.Text); server.Send(msg); } } private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) {// El usuario ha seleccionado un articulo de la lista int fila = e.RowIndex; // El coste lo guardo en una variable global porque lo necesito en otra función coste = Convert.ToInt32(articulosGrid.Rows[fila].Cells[1].Value); if (coste > Convert.ToInt32(disponibleBox.Text)) MessageBox.Show("No puedes comprar ese producto"); else compraBox.Text = articulosGrid.Rows[fila].Cells[0].Value.ToString(); } } CLIENTE 4 (2 forms) public partial class Form1 : Form {Socket server; Thread atender; // Necesitare una lista con los formularios que se crean List<Form2> formularios = new List<Form2>(); delegate void DelegadoParaEscribirResultado(string text); public Form1() {…} private void PonInfo(string text) {this.numLab.Text = text;} private void atender_mensajes_servidor() {//lo mismo de antes switch (op) {case 1: //Me responden la longitud del nombre // Extraigo el identificador de conversación int num = Convert.ToInt32(trozos[1]); // Y ahora extraigo la longitud del nombre int longitud = Convert.ToInt32(trozos[2].Split (',')[0]); //Le envio la información al formulario correspondiente al identificador de conversación formularios[num].TomaLongitud(longitud); break; case 2: //Me responden si mi nombre es bonito // Extraigo el identificador de conversación num = Convert.ToInt32(trozos[1]); // Y ahora extraigo la respuesta string respuesta = trozos[2].Split(',')[0]; //La envio al formulario correspondiente formularios[num].TomaRespuesta(respuesta); break; case 3: // Me indican el número de conectados num = Convert.ToInt32(trozos[1].Split (',')[0]); // Tenemos que escribir num en numLab de manera segura numLab.Invoke(new DelegadoParaEscribirResultado(PonInfo), new object[] { num.ToString()}); break; } } } private void Form1_Load(object sender, EventArgs e) {} private void button1_Click(object sender, EventArgs e) {…} private void button3_Click(object sender, EventArgs e) {…} private void button4_Click(object sender, EventArgs e) {//Ponemos en marcha un nuevo formulario ThreadStart ts; Thread t; int num = formularios.Count; // Creamos un thread que simplemente pondrá en marcha el nuevo formulario.
// Enviamos al thread el numero de orden que servirá de identificador de conversación en los mensajes que se // intercambien con el servidor ts = delegate { atender_conversacion(num); }; t = new Thread(ts); t.Start(); } private void atender_conversacion(int id) {// Este thread simplemente pone en marcha el formulacio para atender al conversación cuyo identificador es id // Creo ese formulario y le paso el socket y el id Form2 f = new Form2(id,server); // añado el formulario a la tabla de hash formularios.Add(f); f.ShowDialog();} public partial class Form2 : Form {int num; Socket server; public Form2(int num, Socket server) {InitializeComponent(); this.num = num; this.server = server; } private void Form2_Load(object sender, EventArgs e) {} private void button2_Click_1(object sender, EventArgs e) {if (Longitud.Checked) {// Solicito longitud del nombre. Envio id de conv y el nombre string mensaje = "1/" + num.ToString() +"/"+ nombre.Text; // Enviamos al servidor el nombre tecleado byte[] msg = System.Text.Encoding.ASCII.GetBytes(mensaje); server.Send(msg); } else {//Pregunto si el nombre es bonito. Envio id de conv y el nom string mensaje = "2/" +num.ToString() +"/"+nombre.Text; // Enviamos al servidor el nombre tecleado byte[] msg = System.Text.Encoding.ASCII.GetBytes(mensaje); server.Send(msg); } } public void TomaLongitud (int longitud) // El formulario principal me entregará con esta función la longitud del nombre, cuando la reciba del servidor {MessageBox.Show("La longitud de tu nombre es: " + longitud); } public void TomaRespuesta (string respuesta) // El formulario principal me entregará con esta función la respuesta recibida del servidor {if (respuesta == "SI") MessageBox.Show("Tu nombre ES bonito."); else MessageBox.Show("Tu nombre NO es bonito. Lo siento."); } Aplicación servicios varios servidores Namespace WindowsFormsApplication1 { public partial class Form1 : Form { Socket server1;Socket server2;Socket server3; delegate void DelegadoParaEscribirResultado(string text); public Form1() {InitializeComponent();} private void atender_mensajes_servidor2(){} atender_mensajes_servidor1() //mismo código con los 3 {Boolean continuar = true; while (continuar) {int op; byte[] msg = new byte[180]; try{ server1.Receive(msg); string mensaje = Encoding.ASCII.GetString(msg); string[] trozos = mensaje.Split('-'); op = Convert.ToInt32(trozos[0]); switch (op) { case 0: MessageBox.Show("Conectado"; this.Invoke(new DelegadoParaEscribirResultado(this.EscribeInfo), new object[] { " Case 0 recibido de server 1" }); //escribe el mensaje en el textbox solo en 1 servidor break; case 1: MessageBox.Show("Usuario Autenticado"); break; }} catch (SocketException e) { MessageBox.Show("Socket error " + e.ErrorCode + ": " + e.Message); continuar = false;}catch (Exception e) // Si se finaliza el servidor inesperadamente{ MessageBox.Show("Source error " + e.Source + ": " + e.Message);continuar = false;}}MessageBox.Show("Finaliza atender a servidor"); } public void EscribeInfo(string text) { this.textBox1.Text = " EscribeInfo: " + text;} private void muestraForm2() {Form2 f2 = new Form2(); f2.ShowDialog();} private void button1_Click(object sender, EventArgs e) {ThreadStart ts3 = delegate { muestraForm2(); }; Thread t3 = new Thread(ts3); t3.Start();} private void Form1_Load(object sender, EventArgs e) { IPAddress direc = IPAddress.Parse("IP Servidor 1"); IPEndPoint ipep = new IPEndPoint(direc, 50004); server1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try{server1.Connect(ipep);} catch (SocketException) { MessageBox.Show("No he podido conectar con el servidor");return; } ThreadStart ts = delegate { atender_mensajes_servidor1(); };Thread atender = new Thread(ts); atender.Start(); // mismo procedimiento con los 3 }}} ...

Comprar Previsualizar