jchat:linux聊天程序4:客户端

makefile:

jchat:        main.o login.o regist.o tcp.o

    gcc -w main.o login.o regist.o tcp.o -o jchat

    rm -f *.o *.gch *~

main.o:        main.c login.h regist.h tcp.h

    gcc -w -c main.c login.h regist.h tcp.h

login.o:    login.c login.h tcp.h

    gcc -w -c login.c login.h tcp.h

regist.o:    regist.c regist.h tcp.h

    gcc -w -c regist.c regist.h tcp.h

tcp.o:        tcp.c tcp.h

    gcc -w -c tcp.c tcp.h



clean:

    rm -f *.o *.gch *~ jchat

 

main.c:

/*client/main.c*/



#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>



#include "login.h"

#include "regist.h"

#include "tcp.h"



#define MAXLINE 4096

#define IP "127.0.0.1" // localhost

#define PORT 12345



char sendbuff[MAXLINE], recvbuff[MAXLINE];//send buffer & recv buffer

int sockfd;//socket file descriptor



int main(int argc, char *argv[])

{

    if ((sockfd = link_server(IP, PORT)) == -1) {

        exit(1);

    }



    char choice[107];

    while (1) {

        printf("login or regist:");

        scanf("%s", choice);

        if (strcmp(choice, "login") == 0) {

            login(sockfd);

        }

        else if (strcmp(choice, "regist") == 0) {

            regist(sockfd);

        }

        else {

            puts("input login or regist!");

        }

    }

}

 

login.c:登录操作

/*client/login.c*/



#include <stdio.h>

#include <unistd.h>

#include <string.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/un.h>



#include "login.h"

#include "tcp.h"



#define MAXLINE 4096

#define IP "127.0.0.1" // localhost

#define PORT 12345



char user[107], passwd[107];

char line[107];



/*

 * login to server

 * return 1 if succeed, 0 if fail

 */

int login_succeed(int sockfd)

{

    char sendbuff[MAXLINE], recvbuff[MAXLINE];

    sprintf(sendbuff, "l:%s:%s", user, passwd);



    write(sockfd, sendbuff, strlen(sendbuff));    

    //printf("sendbuff> '%s'\n", sendbuff);

    int n = read(sockfd, recvbuff, MAXLINE);

    recvbuff[n] = '\0';

    //printf("recvbuff> '%s'\n", recvbuff);



    if (strcmp(recvbuff, "y") == 0) return 1;

    else return 0;

}



/*

 * send message to another user by server

 */

void send_mesg(int sockfd)

{

    char sendbuff[MAXLINE];

    int len = strlen(line);

    int i = 1, j, k, pos;



    while (i<len && (line[i]==' ' || line[i]=='\t')) ++i;

    j = i + 1;

    while (j<len && line[j]!=' ' && line[j]!='\t') ++j;

    k = j + 1;

    while (k<len && (line[k]==' ' || line[k]=='\t')) ++k;



    int send_len = 2, ulen = strlen(user);

    sendbuff[0] = 's';sendbuff[1] = ':';

    for (pos=0; pos<ulen; ++pos) sendbuff[send_len++] = user[pos];

    sendbuff[send_len++] = ':';

    for (pos=i; pos<j; ++pos) sendbuff[send_len++] = line[pos];

    sendbuff[send_len++] = ':';

    for (pos=k; pos<len; ++pos) sendbuff[send_len++] = line[pos];

    sendbuff[send_len++] = '\0';



    write(sockfd, sendbuff, strlen(sendbuff));

    //printf("send_mesg sendbuff> '%s'\n", sendbuff);

}



/*

 * ask the server the online user

 */

void check_online(int sockfd)

{

    char sendbuff[MAXLINE], recvbuff[MAXLINE];

    sprintf(sendbuff, "o");



    write(sockfd, sendbuff, strlen(sendbuff));

    //printf("check_online sendbuff> '%s'\n", sendbuff);

    int recv_len = read(sockfd, recvbuff, MAXLINE);

    recvbuff[recv_len] = '\0';

    //printf("check_online recvbuff> '%s'\n", recvbuff);



    if (recv_len <= 1) {

        printf("no one online\n");

    }

    else {

        int i = 0, j, k, num = 0;

        char on[100][21];

        while (i < recv_len) {

            j = i+1;

            while (recvbuff[j] != ';') ++j;

            for (k=i; k<j; ++k) on[num][k-i] = recvbuff[k];

            on[num][j-i] = '\0';

            ++num;

            i = j + 1;

        }

        printf("%d online user:\n", num);

        for (k=0; k<num; ++k) printf("  %s\n", on[k]);

    }

}



/*

 * quit this client

 * quit the process fork by server

 */

void quit(int sockfd)

{

    char sendbuff[MAXLINE];

    sprintf(sendbuff, "q:%s", user);



    write(sockfd, sendbuff, strlen(sendbuff));

    //printf("quit sendbuff> '%s'\n", sendbuff);

}



/*

 * get unread message from server every 1 second

 */

void get_mesg(int sockfd)

{

    char sendbuff[MAXLINE], recvbuff[MAXLINE];



    while (1) {

        sleep(1);



        sprintf(sendbuff, "g:%s", user);

        write(sockfd, sendbuff, strlen(sendbuff));



        //printf("get_mesg sendbuff> '%s'\n", sendbuff);

        int recv_len = read(sockfd, recvbuff, MAXLINE);

        recvbuff[recv_len] = '\0';

        //printf("get_mesg recvbuff> '%s'\n", recvbuff);



        if (recv_len <= 1) { // no message get

            continue;

        }



        int num, i, j, k, l;

        num = i = 0;

        char on[100][21];

        while (i < recv_len) {

            j = i + 1;

            while (recvbuff[j] != ';') ++j;



            k = i;

            while (k<j && recvbuff[k]!=':') ++k;

            int line_len = 0;

            for (l=i; l<k; ++l) line[line_len++] = recvbuff[l];

            line[line_len++] = ':';line[line_len++] = ' ';

            for (l=k+1; l<j; ++l) line[line_len++] = recvbuff[l];

            line[line_len] = '\0';

            puts(line);



            i = j + 1;

        }

    }

}



/*

 * send online notice to server every 5 seconds

 */

void online_notice(int sockfd)

{

    char sendbuff[MAXLINE];



    while (1) {

        sprintf(sendbuff, "a:%s", user);



        write(sockfd, sendbuff, strlen(sendbuff));

        //printf("sendbuff> '%s'\n", sendbuff);



        sleep(5);

    }

}



/*

 * everything after login

 * thread 1 : receive user command

 * thread 2 : get unread message from server

 * thread 3 : send online notice to server

 */

void login(int sockfd)

{

    printf("user: ");

    scanf("%s", user);

    printf("password: ");

    scanf("%s", passwd);



    if (login_succeed(sockfd)) {

        printf("welcome %s~\n", user);

        pid_t pid1 = fork();

        if (pid1 != 0) {

            pid_t pid2 = fork();

            if (pid2 != 0) { // thread 1 : input command

                while (gets(line)) {

                    switch (line[0]) {

                        case 's': // send message

                            send_mesg(sockfd);

                            break;

                        case 'o': // check online

                            check_online(sockfd);

                            break;

                        case 'q': // quit

                            quit(sockfd);

                            kill(pid1, 9);

                            kill(pid2, 9);

                            printf("goobye %s ~\n", user);

                            exit(0);

                            break;

                    }

                }

            }

            else { // thread 2 : get message from server

                get_mesg(sockfd);

            }

        }

        else { // thread 3 : send online notice

            online_notice(sockfd);

        }

    }

    else {

        printf("login failed\n");

    }

}

 

login.h:

/*client/login.h*/



#ifndef LOGIN_H

#define LOGIN_H



void login(int sockfd);



#endif // LOGIN_H

 

regist.c:注册操作

/*client/regist.c*/



#include <stdio.h>

#include <unistd.h>

#include <string.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/un.h>



#include "regist.h"

#include "tcp.h"



#define MAXLINE 4096



extern char sendbuff[MAXLINE], recvbuff[MAXLINE];

char user[107], passwd[107];



/*

 * regist new user

 * return 1 if succeed, 0 if fail

 */

int regist_succeed(int sockfd)

{

    sprintf(sendbuff, "r:%s:%s", user, passwd);



    write(sockfd, sendbuff, strlen(sendbuff));

    int n = read(sockfd, recvbuff, MAXLINE);

    recvbuff[n] = 0;



    if (strcmp(recvbuff, "y") == 0) return 1;

    else return 0;

}



/*

 * regist

 */

void regist(int sockfd)

{

    printf("user: ");

    scanf("%s", user);

    printf("password: ");

    scanf("%s", passwd);



    if (regist_succeed(sockfd)) {

        printf("regist a new user!\n");

    }

    else {

        printf("fail in regist new user!\n");

    }

}

 

regist.h:

/*client/regist.h*/



#ifndef REGIST_H

#define REGIST_H



void regist(int sockfd);



#endif // REGIST_H

 

tcp.c:建立与服务器的连接

/*client/tcp.c*/



#include <stdio.h>

#include <unistd.h>

#include <string.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/un.h>

#include <netinet/in.h>



#include "tcp.h"



/*

 * link to assign IP and port

 * return the socket file descriptor

 */

int link_server(char *IP, int port)

{

    int sockfd;

    struct sockaddr_in servaddr;



    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {

        fprintf(stderr, "socket error\n");

        return -1;

    }



    memset(&servaddr, 0, sizeof(servaddr));

    servaddr.sin_family = AF_INET;

    servaddr.sin_port = htons(port);

    if (inet_pton(AF_INET, IP, &servaddr.sin_addr) <= 0) {

        fprintf(stderr, "inet_pton error for %s\n", IP);

        return -1;

    }



    if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {

        fprintf(stderr, "connect error\n");

        return -1;

    }



    return sockfd;

}

 

tcp.h:

/*client/tcp.h*/



#ifndef TCP_H

#define TCP_H



/*

 * link IP:port using tcp

 * return sock file descriptor of the link (-1 if error)

 */

int link_server(char *IP, int port);



#endif // TCP_H

 

你可能感兴趣的:(linux)