Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Problema con cliente sockets

Estas en el tema de Problema con cliente sockets en el foro de C/C++ en Foros del Web. buenas , estoy haciendo un cliente-servidor en c++ , ya llevo prácticamente todo, los clientes entran y pueden mandar mensajes a todos los clientes y ...
  #1 (permalink)  
Antiguo 04/12/2014, 15:04
 
Fecha de Ingreso: febrero-2014
Ubicación: Guadalajara
Mensajes: 34
Antigüedad: 10 años, 10 meses
Puntos: 0
Problema con cliente sockets

buenas , estoy haciendo un cliente-servidor en c++ , ya llevo prácticamente todo, los clientes entran y pueden mandar mensajes a todos los clientes y eso lo hace de maravilla. En lo que me atoré es como hacer que un cliente mande un mensaje a otro cliente sin que se mande a los demas. o sea que sea tipo mensaje personal y no grupal .
cabe resaltar que mi cliente- servidor ya hace mensajes grupales pero faltan los mensajes de un cliente a otro en especifico.


codigo Serever

Código:
#include "stdafx.h"
#undef UNICODE 
#define  WIN32_LEAN_AND_MEAN 

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <string>



using namespace std;

stringstream sstm;

#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_PORT "27015"
#define MAX 100

bool acept(SOCKET  Misocket);
bool NonBlock_Recv(SOCKET s, char* Buffer);

SOCKET ClientSocket[MAX];
int iContador = 0;

int _tmain(int argc, _TCHAR* argv[])
{

	char MyMessage[100] = "";
	SOCKET ListenSocket = INVALID_SOCKET;


	WSADATA	 wsaData;
	int  iResult;
	int iClient = 0;

	
	struct addrinfo *result = NULL;
	struct addrinfo hints;

	int iSendResult;
	



	char Mimensaje[128] = "";


	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

	if (iResult != 0) {
		cout << "WSAStartup fallo  con : " << iResult << endl;
		WSACleanup();
		return -1;
	}
	cout << "WSAStartup.....ok" << endl;


	ZeroMemory(&hints, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	hints.ai_flags = AI_PASSIVE;

	iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);

	if (iResult != 0) {

		cout << "getAddrInfo  fallo con: " << iResult << endl;
		WSACleanup();
		return -1;

	}
	cout << "Get AdrrInfo....Ok" << endl;


	ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
	if (ListenSocket == INVALID_SOCKET) {

		cout << "Socket fallo con error" << WSAGetLastError() << endl;
		FreeAddrInfo(result);
		WSACleanup();
		return -1;
	}

	cout << "Socket.....ok" << endl;

	iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);

	if (iResult == SOCKET_ERROR) {

		cout << " bind fallo con error:" << WSAGetLastError() << endl;
		freeaddrinfo(result);
		closesocket(ListenSocket);
		WSACleanup();
		return -1;
	}
	freeaddrinfo(result);
	cout << "Bind....ok" << endl;



	iResult = listen(ListenSocket, SOMAXCONN);

	if (iResult == SOCKET_ERROR) {

		cout << "listen fallo con error ...." << WSAGetLastError() << endl;
		closesocket(ListenSocket);
		WSACleanup();
		return -1;
	}

	cout << "Listen...ok" << endl;
	
	
	
	while (true)
	{
		int i = 0;
		if (acept(ListenSocket))
			iContador++;
		while (i < iContador)
		{
			char Mensaje[100] = "";

			if (NonBlock_Recv(ClientSocket[i], Mensaje)) 
			{
				int len;
				cout << "Cliente " << i << ": " << Mensaje << endl;
				len = strlen(Mensaje);
		
				for (int cont=0; cont < iContador; cont++) {
				
				
					if (cont == i) {
						send(ClientSocket[cont], "I am:" , 100, 0);
						send(ClientSocket[cont], Mensaje, len, 0);

					}else {
						
						char message[128]="";
						
						sprintf_s(message, "cliente %i dijo:", i);
						send(ClientSocket[cont], message, 128, 0);
						send(ClientSocket[cont], Mensaje, 100, 0);
					
					}
				    
				
				}
		
			}

			i++;
		}


	}
	 system("pause");
    return 0;
}


bool acept(SOCKET  Misocket) {

	fd_set object;  
	FD_ZERO(&object); 
	FD_SET(Misocket, &object);
	timeval time; 
	time.tv_sec = 0; 
	time.tv_usec = 0; 

	  static  int iClient = 0;  
	if (select(1, &object, NULL, NULL, &time)) {
	

		ClientSocket[iClient] = accept(Misocket, NULL, NULL);
		cout << "Cliente " << iClient <<":"<< endl; 
	    char message[128] = " "; 
        sprintf_s(message, "Eres el cliente %i.", iClient);
		int Size = strlen(message);
			
		send(ClientSocket[iClient], message, Size, 0);
		
		iClient++;
		return true;
	}

	return false; 



}

bool NonBlock_Recv(SOCKET s, char* Buffer)
{
	fd_set readSet;//es un set
	FD_ZERO(&readSet);//limpia ek set
	FD_SET(s, &readSet); //agrega al set
	timeval time;//para ver cuanto tiempo debemos esperar
	time.tv_sec = 0;//segundos
	time.tv_usec = 0;//milisegundos
	if (select(1, &readSet, NULL, NULL, &time))
	{
		recv(s, Buffer, 100, NULL);
		return true;
	}
	return false;
}

codigo cliente

Código:
  #include "stdafx.h"
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include<conio.h>
#include<iostream>
#include<string.h>


#pragma comment(lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")

#define DEFAULT_BUFLEN 128
#define DEFAULT_PORT "27015"
#define ENTER 13

using namespace std;
bool NonBlockGetLine(char* sz);
bool NonBlock_Recv(SOCKET s, char* szBuffer);


int _tmain(int argc, _TCHAR* argv[])
{

	WSADATA	 wsaData;
	int  iResult;


	

	struct addrinfo *result = NULL, *ptr = NULL;
	struct addrinfo hints;

	int iSendResult=0;
	

	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
		cout << "WSAStartup fallo  con : " << iResult << endl;
		WSACleanup();
		return -1;
	}
	cout << "WSAStartup.....ok" << endl;


	ZeroMemory(&hints, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	//hints.ai_flags = AI_PASSIVE;


	iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
	if (iResult != 0) {

		cout << "getAddrInfo  fallo con: " << iResult << endl;
		WSACleanup();
		return -1;

	}
	cout << "Get AdrrInfo....Ok" << endl;


	SOCKET ConnectSocket = INVALID_SOCKET;
	ConnectSocket = socket(result->ai_family, result->ai_socktype,
		result->ai_protocol);
	if (ConnectSocket == INVALID_SOCKET) {
		WSACleanup();
		return 1;
	}


	cout << "Socket.....ok" << endl;


	iResult = connect(ConnectSocket, result->ai_addr, result->ai_addrlen);
	if (iResult)
		cout << "Error" << endl;
	else
		cout << "Se conecto" << endl;

	
	char msj[100] = "";
	int msjlen = 0;

	

	while (true)
	{
		
		
		
		
		if (NonBlockGetLine(msj))
		{
			msjlen = strlen(msj);
			send(ConnectSocket, msj, msjlen, 0);
		}
		char MsjRecv1[100] = "";
		char MsjRecv2[100] = "";
		
		if (NonBlock_Recv(ConnectSocket, MsjRecv1))
		{
			cout << endl << MsjRecv1 << endl;
	
			if (NonBlock_Recv(ConnectSocket, MsjRecv2))
			{
				cout << MsjRecv2 << endl;
			}
		}
	}


	system("Pause");
	return 0;

}




bool NonBlockGetLine(char* sz)
{
	static int iCont = 0;
	if (_kbhit())
	{
		sz[iCont] = _getche();
		iCont++;
		if (sz[iCont - 1] == ENTER)
		{
			sz[iCont - 1] = 0;
			iCont = 0;
			return true;
		}
	}
	return false;
}


bool NonBlock_Recv(SOCKET s, char* szBuffer)
{
	fd_set readSet;
	FD_ZERO(&readSet);
	FD_SET(s, &readSet);
	timeval time;
	time.tv_sec = 0;
	time.tv_usec = 0;
	if (select(1, &readSet, NULL, NULL, &time))
	{
		recv(s, szBuffer, 128, 0);
		return true;
		
	}
	return false;
}
  #2 (permalink)  
Antiguo 04/12/2014, 16:35
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 12 años, 5 meses
Puntos: 28
Respuesta: Problema con cliente sockets

En vez de enviar una cadena de caracteres, envia una estructura. Le metes un campo que indique si es un mensaje privado o es un mensaje para todos.

Y el servidor se encarga de interpretarlo y hacer lo consecuente.
  #3 (permalink)  
Antiguo 04/12/2014, 22:22
 
Fecha de Ingreso: febrero-2014
Ubicación: Guadalajara
Mensajes: 34
Antigüedad: 10 años, 10 meses
Puntos: 0
Respuesta: Problema con cliente sockets

Muchas gracias pero , la verdad no me quedo claro , como hacerlo, me podrías dar un ejemplo si serías tan amable , me serviría de mucho
  #4 (permalink)  
Antiguo 04/12/2014, 22:24
 
Fecha de Ingreso: febrero-2014
Ubicación: Guadalajara
Mensajes: 34
Antigüedad: 10 años, 10 meses
Puntos: 0
Respuesta: Problema con cliente sockets

Muchas gracias pero , la verdad no me quedo claro , como hacerlo, me podrías dar un ejemplo si serías tan amable , me serviría de mucho
  #5 (permalink)  
Antiguo 05/12/2014, 00:28
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 2 meses
Puntos: 204
Respuesta: Problema con cliente sockets

Cita:
Iniciado por superchava666 Ver Mensaje
Muchas gracias pero , la verdad no me quedo claro , como hacerlo, me podrías dar un ejemplo si serías tan amable , me serviría de mucho
Ese código lo has escrito tu o lo has copiado de algún otro sitio?

Lo que te está diciendo amchacon no es nada del otro mundo y, si realmente el código que has publicado es tuyo, deberías saber de qué te está hablando...

En cualquier caso. Para poder tener un control sobre los reenvios de mensajes, tienes que configurar el mensaje para que sea capaz de contener información que pueda ser interpretada por el cliente y el servidor. Ya no vale enviar el mensaje en "crudo", hay que habilitar algún tipo de mecanismo que permita enviar información de control. ¿Cómo se hace eso? varias opciones, yo te pongo una de las más sencillas:

* Creas una estructura fija. Algo del tipo:

Código C:
Ver original
  1. struct trama
  2. {
  3.   int destinatario;
  4.   char mensaje[50];
  5. };
Entonces, puedes decidir que si "destinatario" es igual a 0 entonces el mensaje se envía a todo el mundo y en caso contrario solo al destinatario indicado.

De lo que se trata entonces es de que los clientes envíen al servidor una estructura de este estilo.

Un saludo.

Etiquetas: char, cliente, int, sockets
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:23.