c TCP聊天程序,客户端don';我不知道什么时候收

c TCP聊天程序,客户端don';我不知道什么时候收,c,tcpclient,C,Tcpclient,我想构建一个聊天程序,但问题是,一旦客户端向服务器发送消息,所有其他客户端都会从服务器接收该消息,但客户端不知道消息何时会出现。在客户端的主循环中,它将阻塞fgets()并等待用户输入命令或消息。我需要客户端程序接收消息并打印它,同时等待用户的输入。我该怎么做 代码如下: 因为我不知道把它放在哪里,所以我还没有为这个消息写recv #include <stdio.h> #include <stdlib.h> #include <string.h> #inclu

我想构建一个聊天程序,但问题是,一旦客户端向服务器发送消息,所有其他客户端都会从服务器接收该消息,但客户端不知道消息何时会出现。在客户端的主循环中,它将阻塞fgets()并等待用户输入命令或消息。我需要客户端程序接收消息并打印它,同时等待用户的输入。我该怎么做

代码如下: 因为我不知道把它放在哪里,所以我还没有为这个消息写recv

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <time.h>

#define LOGIN 1
#define LO_ACK 2
#define LO_NACK 3
#define EXIT 4
#define JOIN 5
#define JN_ACK 6
#define JN_NACK 7
#define LEAVE_SESS 8
#define NEW_SESS 9
#define NS_ACK 10
#define MESSAGE 11
#define QUERY 12
#define QU_ACK 13

struct packet {
    unsigned int type;
    unsigned int size;
    char source[20];
    char data[500];
};

int encode(struct packet temp, char *data) {

    sprintf(data, "%d:%d:%s:", temp.type, temp.size,
            temp.source);

    int length = strlen(data);

    int i;
    for (i = 0; i < temp.size; i++) {
        data[length + i] = temp.data[i];
    }
    data[length + i] = '\0';

    return length;
}

struct packet decode(char *data) {
    int i, j;
    struct packet message;
    char temp[100];
    char source[20];

    sscanf(data, "%d:%d", &message.type, &message.size);

    sprintf(temp, "%d:%d", message.type, message.size);

    int length = strlen(temp);

    for (i = length + 1; data[i] != ':'; i++) {
        message.source[i - length - 1] = data[i];
    }

    for (j = 0; j < message.size; j++) {
        message.data[j] = data[j + i + 1];
    }

    return message;

}

int main(void) {
    int sockfd, numbytes;
    struct addrinfo hints, *servinfo, *p;
    int rv;
    int login = 0;
    char me[20];


    while (1) {
        char buf[500];
        char input[100];
        char *command;
        char arg1[20], arg2[20], arg3[20], arg4[20], arg5[20];
        int i, j, k, l, m;

        fgets(input, 100, stdin);

        if (strlen(input) < 3)
            continue;

        if (input[0] == '/') {//command
            command = &input[1];

            //get first argument
            for (i = 0; command[i] != '\0' && command[i] != ' '; i++) {
                arg1[i] = command[i];
            }
            //arg1[i] = '\0';

            if (strcmp(arg1, "login") == 0) {//login
                //get id,password,ip,port
                if (login == 1) {
                    printf("error: already login\n");
                    continue;
                }

                for (j = i + 1; command[j] != '\0' && command[j] != ' '; j++) {//id
                    arg2[j - i - 1] = command[j];
                }
                //arg1[j-i+1] = '\0';
                for (k = j + 1; command[k] != '\0' && command[k] != ' '; k++) {//password
                    arg3[k - j - 1] = command[k];
                }

                for (l = k + 1; command[l] != '\0' && command[l] != ' '; l++) {//ip
                    arg4[l - k - 1] = command[l];
                }

                for (m = l + 1; command[m] != '\0'; m++) {//port
                    arg5[m - l - 1] = command[m];
                }

                memset(&hints, 0, sizeof hints);
                hints.ai_family = AF_UNSPEC;
                hints.ai_socktype = SOCK_STREAM;

                if ((rv = getaddrinfo(arg4, arg5, &hints, &servinfo)) != 0) {
                    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
                    return 1;
                }

                for (p = servinfo; p != NULL; p = p->ai_next) {
                    if ((sockfd = socket(p->ai_family, p->ai_socktype,
                            p->ai_protocol)) == -1) {
                        perror("client: socket");
                        continue;
                    }
                    if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
                        close(sockfd);
                        perror("client: connect");
                        continue;
                    }
                    break;
                }

                if (p == NULL) {
                    fprintf(stderr, "client: failed to connect\n");
                    return 2;
                }

                freeaddrinfo(servinfo);

                struct packet tosend;
                tosend.type = LOGIN;
                sprintf(tosend.data, "%s %s", arg2, arg3);
                strcpy(tosend.source, arg2);
                tosend.size = strlen(tosend.data);

                char message[500];
                encode(tosend, message);

                send(sockfd, message, strlen(message), 0);

                usleep(100);
                recv(sockfd, buf, strlen(buf), 0);
                struct packet reply;
                reply = decode(buf);

                if (reply.type == LO_ACK) {
                    printf("login successful\n");
                    strcpy(me, arg2);
                    login = 1;
                    continue;
                } else if (reply.type == LO_NACK) {
                    printf("login failed: %s\n", reply.data);
                    continue;
                }

            } else if (strcmp(arg1, "createsession") == 0) {
                if (login == 0) {
                    printf("error: not login\n");
                    continue;
                }

                for (j = i + 1; command[j] != '\0'; j++) {//session name
                    arg2[j - i - 1] = command[j];
                }

                struct packet tosend;
                tosend.type = NEW_SESS;
                strcpy(tosend.data, arg2);
                strcpy(tosend.source, me);
                tosend.size = strlen(tosend.data);

                char message[500];
                encode(tosend, message);

                send(sockfd, message, strlen(message), 0);

                usleep(100);
                recv(sockfd, buf, strlen(buf), 0);
                struct packet reply;
                reply = decode(buf);

                if (reply.type == NS_ACK) {
                    printf("create session successful\n");
                    continue;
                } else if (reply.type == JN_ACK) {
                    printf("session already exist, join session successful\n");
                    continue;
                }
            } else if (strcmp(arg1, "joinsession") == 0) {
                if (login == 0) {
                    printf("error: not login\n");
                    continue;
                }

                for (j = i + 1; command[j] != '\0'; j++) {//session name
                    arg2[j - i - 1] = command[j];
                }

                struct packet tosend;
                tosend.type = JOIN;
                strcpy(tosend.data, arg2);
                strcpy(tosend.source, me);
                tosend.size = strlen(tosend.data);

                char message[500];
                encode(tosend, message);

                send(sockfd, message, strlen(message), 0);

                usleep(100);
                recv(sockfd, buf, strlen(buf), 0);
                struct packet reply;
                reply = decode(buf);

                if (reply.type == JN_ACK) {
                    printf("join session successful\n");
                    continue;
                }
            } else if (strcmp(arg1, "leavesession") == 0) {
                if (login == 0) {
                    printf("error: not login\n");
                    continue;
                }

                struct packet tosend;
                tosend.type = LEAVE_SESS;
                strcpy(tosend.data, "none");
                strcpy(tosend.source, me);
                tosend.size = strlen(tosend.data);

                char message[500];
                encode(tosend, message);

                send(sockfd, message, strlen(message), 0);

                printf("leave session successful\n");

                continue;
            } else if (strcmp(arg1, "list") == 0) {
                if (login == 0) {
                    printf("error: not login\n");
                    continue;
                }

                struct packet tosend;
                tosend.type = QUERY;
                strcpy(tosend.data, "none");
                strcpy(tosend.source, me);
                tosend.size = strlen(tosend.data);

                char message[500];
                encode(tosend, message);

                send(sockfd, message, strlen(message), 0);

                usleep(100);
                recv(sockfd, buf, strlen(buf), 0);
                struct packet reply;
                reply = decode(buf);

                printf("%s", reply.data);

                continue;
            } else {
                printf("invalid command\n");
                continue;
            }

        } else {//message
            if (login == 0) {
                printf("error: not login\n");
                continue;
            }

            struct packet tosend;
            tosend.type = MESSAGE;
            strcpy(tosend.data, input);
            strcpy(tosend.source, me);
            tosend.size = strlen(tosend.data);

            char message[500];
            encode(tosend, message);

            send(sockfd, message, strlen(message), 0);

            continue;
        }
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义登录名1
#定义LO_ACK 2
#定义LO_NACK 3
#定义出口4
#定义联接5
#定义JN_ACK 6
#定义JN_NACK 7
#定义假期8
#定义新的步骤9
#定义NS_ACK 10
#定义消息11
#定义查询12
#定义QU_ACK 13
结构包{
无符号整数类型;
无符号整数大小;
字符源[20];
字符数据[500];
};
int编码(结构数据包温度,字符*数据){
sprintf(数据,“%d:%d:%s:”,临时类型,临时大小,
温度源);
int length=strlen(数据);
int i;
对于(i=0;iai_next){
如果((sockfd=socket(p->ai_族,p->ai_socktype,
p->ai_协议)=-1){
perror(“客户端:套接字”);
继续;
}
如果(连接(sockfd,p->ai_addr,p->ai_addrlen)=-1){
关闭(sockfd);
perror(“客户:连接”);
继续;
}
打破
}
if(p==NULL){
fprintf(stderr,“客户端:连接失败\n”);
返回2;
}
freeaddrinfo(servinfo);
结构包发送;
tosend.type=登录名;
sprintf(tosend.data,“%s%s”,arg2,arg3);
strcpy(tosend.source,arg2);
tosend.size=strlen(tosend.data);
字符消息[500];
编码(发送、消息);
发送(sockfd,message,strlen(message),0);
usleep(100);
recv(sockfd,buf,strlen(buf),0);
结构包应答;
回复=解码(buf);
如果(reply.type==LO_ACK){
printf(“登录成功\n”);
strcpy(me,arg2);
登录=1;
继续;
}else if(reply.type==LO_NACK){
printf(“登录失败:%s\n”,reply.data);
继续;
}
}else if(strcmp(arg1,“createsession”)==0){
如果(登录==0){
printf(“错误:未登录\n”);
继续;
}
对于(j=i+1;命令[j]!='\0';j++){//会话名称
arg2[j-i-1]=命令[j];
}
结构包发送;
tosend.type=新的;
strcpy(tosend.data,arg2);
strcpy(tosend.source,me);
tosend.size=strlen(tosend.data);
字符消息[500];
编码(发送、消息);
发送(sockfd,message,strlen(message),0);
usleep(
#include <stdio.h>
#include <sys/select.h>
#include <unistd.h>

 int main()
 {

    fd_set fds;

    while(1){
        FD_ZERO(&fds); // you NEED to zero this every loop
        FD_SET(STDIN_FILENO, &fds);
        // add your socket here

        // first argument here will be your socket + 1
        select(STDIN_FILENO + 1, &fds, NULL, NULL, NULL);
        if (FD_ISSET(STDIN_FILENO, &fds)){
              char buffer[128];
              fgets(buffer, sizeof(buffer), stdin);
              printf("User input - stdin: %s", buffer);
        }
        // here check if your socket is set and act accordingly
     }

     return 0;
 }