当前位置: 首页 > 知识库问答 >
问题:

插座-客户端双打印

裴甫
2023-03-14

我正在使用套接字开发一个简单的聊天应用程序。它是客户机-服务器驱动的。除了这个我找不到的bug,一切都很完美:如果我是第一个连接到服务器的客户机,我收到的每一条消息都会在屏幕上打印一次(就像它应该的那样)。然而,如果我是第二个连接的客户,我收到的每条消息都会打印两次,第三个客户会看到他的消息三次,以此类推

当我通过插座收到东西时,我像这样打印它:

printf (" >%s \n", received);

因此,如果我收到用户“charles”发送的消息hello,我会打印消息“

我将感激任何帮助。以下是从socket接收的部分代码:

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)。当服务器需要发送消息时,我会浏览用户数组,并仅在该用户位于同一聊天室时才将消息发送给该用户。谢谢。

共有1个答案

长孙修远
2023-03-14

你不用检查返回了多少字节。它不必读取所有未完成的数据。您可能需要循环读取,直到接收到所有字节。

 类似资料:
  • 问题 你想通过网络提供持续的服务,与客户保持持续的联系。 解决方案 创建一个双向 TCP 客户机。 在 Node.js 中 net = require 'net' domain = 'localhost' port = 9001 ping = (socket, delay) -> console.log "Pinging server" socket.write "Ping"

  • 我正在实现Spring WebFluxendpoint,它应该从套接字获取数据。IO客户端Java。 我不明白如何将传入数据收集到Flux流中。我可以创建新的Flux并订阅该传入数据吗?感谢您的建议。

  • 打开客户端 /** * * @param {String} _url 户动客户端后打开的url 不传默认唤起客户端 * @param {String} _clinet 默认打开手淘,取值为"tmall"时打开手机天猫 * @example * Tida.openClient(); */ Tida.openClient( _url, _clinet );

  • 我试图了解Socketchannes和NIO的总体情况。我知道如何使用常规套接字,以及如何为每个客户机服务器创建一个简单的线程(使用常规阻塞套接字)。 所以我的问题是: 什么是袜子通道 当我使用SocketChannel而不是Socket时,额外得到了什么 通道和缓冲区之间的关系是什么 什么是选择器 文档中的第一句话是

  • 问题内容: Java 类有两种方法,分别检查套接字是关闭还是连接。我想知道仅开放的TCP套接字与开放和连接的TCP套接字有什么区别,这与UDP有何不同。 问题答案: 为了把事情简单地说,这是 开放的 是要么等待连接或已与另一个成功连接的插座。当一个套接字被 关闭 ,这意味着这个套接字没有连接不再可用,而且它的资源已被释放。一个已连接的好,这意味着该套接字已连接到另一个。 这样可以 同时打开并连接。

  • 有人有任何示例代码来演示在java客户端接收消息socket.io? 还有,有没有从同一个套接字发送文件/二进制文件/图片的例子。io java客户端?(基本上是来自java而非javascript客户端的示例代码) android java client的版本可以在这里获得(该版本声称它可以与socket.io 1.0及更高版本一起使用)(似乎是最新的版本)https://github.com/