我正在开发一个使用套接字的简单聊天应用程序。它是客户端 - 服务器驱动的。 一切工作完美,除了这个错误,我无法找到:如果我是第一个连接到服务器的客户端,我收到的每一条消息只是在屏幕上打印一次(因为它应该是)。尽管如此,如果我是连接的第二个客户,我收到的每条消息都会打印两次,第三个客户会看到他的消息三次,依此类推。我真的快疯了,因为这样:套接字 - 客户端双面打印
当我通过socket收到的东西,我打印出来是这样的:
printf (" >%s \n", received);
因此,如果我得到的消息hello,由用户“查尔斯·发送“我打印信息>> charles:hello”,令我感到惊讶的是,重复的照片没有添加的“>”字符(重复的将是“charles:hello”),因此我无法找到在哪里正在进行打印(上面的printf()
是我的代码中唯一的printf()
)。
我会很感激任何帮助。以下是从套接字接收的代码部分:
while (1) {
recv(newsockfd, recibido, 255, 0);
printf (">%s \n",recibido);
}
此代码由线程执行。
谢谢,伙计们。
下面是客户端的全码:
void *Atender(void *estructura){
DATOS *info;
info = (DATOS *)estructura;
int newsockfd=info->socket;
char recibido[255];
memset(recibido,1,255);
while (1){
recv(newsockfd, recibido, 255, 0);
printf (">%s \n",recibido);
memset(recibido,0,255);
}
}
main(int argc, char *argv[]) {
int sockfd;
struct sockaddr_in serveraddr;
char *server;
Hilos = malloc((200)*sizeof(pthread_t));
/* Remember the program name for error messages. */
programname = argv[0];
//Realizo lectura e imprimo para chequear que se leyo todo bien.
lectura(argv,argc);
/* Who's the server? */
server=host;
/* Get the address of the server. */
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(server);
serveraddr.sin_port = htons(atoi(puerto));
/* Open a socket. */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
fatalerror("can't open socket");
/* Connect to the server. */
if (connect(sockfd, (struct sockaddr *) &serveraddr,
sizeof(serveraddr)) < 0)
fatalerror("can't connect to server");
enviarInfoInicial(sockfd,nombre,"Actual");
char buff[200];
memset(buff,1,200);
//Creacion del hilo que se quedara siempre escuchando
DATOS d;
d.socket=sockfd;
pthread_create(&Hilos[iterador_hilos],NULL,Atender,(void *)&d);
iterador_hilos++;
//El que no es un hilo se queda siempre esperando por si se quiere
//introducir un comando
while (1) {
fgets(buff, sizeof buff, stdin);
mandarInstruccion(sockfd,buff);
if ((buff[0] == 'f') & (buff[1] == 'u') & (buff[2] == 'e')){
printf("Cchat se ha cerrado. \n");
close(sockfd);
exit(0);
}
memset(buff,1,200);
}
}
的代码是西班牙语,但总的想法是可以理解的。 DATOS
结构只是传递给创建的线程的结构,并且只包含该线程将从中读取的套接字(以前发布的while(1)
)。 “ATENDER”是线程执行的过程。
下面是来自服务器的相关代码:
void EjecutarInstruccion(char tipo[],char argumento[],char usuario[]) {
if (!strcmp(tipo,"men")) {
char sala[20];
char total[300];
memset(total,0,300);
strcpy(sala,ObtenerSalaUsuario(usuario));
int i=0;
for (i;i<200;i++) {
if (!strcmp((lusuarios[i].sala),sala)) {
strcat(total,usuario);
strcat(total,": ");
strcat(total,argumento);
send (lusuarios[i].socket, total, strlen(total)+1, 0);
}
}
}
}
在服务器端,我有用户的数组,每个用户包含自己的用户名,聊天室,他是在和他的插座(的FD)。当服务器需要发送消息时,只有当他在同一个聊天室中时,我才会浏览该用户阵列并将该消息发送给该用户。 谢谢。
如果您希望我们发现错误,您需要发布您的客户端和服务器代码。 – simonc
好的,我现在就添加它 – CDS18
你应该发布相关的服务器代码,因为这可能是发送相同的消息。 – Duck