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[])
{
    ) {
        exit();
    }

    ];
    ) {
        printf("login or regist:");
        scanf("%s", choice);
        ) {
            login(sockfd);
        }
        ) {
            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

], passwd[];
];

/*
 * 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);

    ) ;
    ;
}

/*
 * send message to another user by server
 */
void send_mesg(int sockfd)
{
    char sendbuff[MAXLINE];
    int len = strlen(line);
    , j, k, pos;

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

    , ulen = strlen(user);
    sendbuff[] = ] = ':';
    ; 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);

    ) {
        printf("no one online\n");
    }
    else {
        , j, k, num = ;
        ][];
        while (i < recv_len) {
            j = i+;
            while (recvbuff[j] != ';') ++j;
            for (k=i; k<j; ++k) on[num][k-i] = recvbuff[k];
            on[num][j-i] = '\0';
            ++num;
            i = j + ;
        }
        printf("%d online user:\n", num);
        ; 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];

    ) {
        sleep();

        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);

        ) { // no message get
            continue;
        }

        int num, i, j, k, l;
        num = i = ;
        ][];
        while (i < recv_len) {
            j = i + ;
            while (recvbuff[j] != ';') ++j;

            k = i;
            while (k<j && recvbuff[k]!=':') ++k;
            ;
            for (l=i; l<k; ++l) line[line_len++] = recvbuff[l];
            line[line_len++] = ':';line[line_len++] = ' ';
            ; l<j; ++l) line[line_len++] = recvbuff[l];
            line[line_len] = '\0';
            puts(line);

            i = j + ;
        }
    }
}

/*
 * send online notice to server every 5 seconds
 */
void online_notice(int sockfd)
{
    char sendbuff[MAXLINE];

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

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

        sleep();
    }
}

/*
 * 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();
        ) {
            pid_t pid2 = fork();
            ) { // thread 1 : input command
                while (gets(line)) {
                    ]) {
                        case 's': // send message
                            send_mesg(sockfd);
                            break;
                        case 'o': // check online
                            check_online(sockfd);
                            break;
                        case 'q': // quit
                            quit(sockfd);
                            kill(pid1, );
                            kill(pid2, );
                            printf("goobye %s ~\n", user);
                            exit();
                            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];
], passwd[];

/*
 * 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] = ;

    ) ;
    ;
}

/*
 * 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;

    )) < ) {
        fprintf(stderr, "socket error\n");
        ;
    }

    memset(&servaddr, , sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port);
    ) {
        fprintf(stderr, "inet_pton error for %s\n", IP);
        ;
    }

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

    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

jchat:linux聊天程序4:客户端的更多相关文章

  1. jchat:linux聊天程序1:简介

    做一个linux的聊天软件,虽然没什么创意,但是它可以用来锻炼和测试我对网络编程的掌握程度,也借此机会做一些有意思的程序. 这里做的是linux下一个命令行的客户端与服务器的聊天程序,没写界面,因为对 ...

  2. jchat:linux聊天程序3:服务器

    makefile: jchat_server: main.o process.o sql.o gcc -o jchat_server main.o process.o sql.o -L/usr/lib ...

  3. jchat:linux聊天程序2:MySQL

    该软件使用的数据库为MySQL,因为它免费.开源,在linux下几乎就是最好的选择. 首先要在mysql中root用户新建数据库并赋权给本用户: create database jchat; gran ...

  4. boost asio异步读写网络聊天程序客户端 实例详解

    boost官方文档中聊天程序实例讲解 数据包格式chat_message.hpp <pre name="code" class="cpp">< ...

  5. Socket聊天程序——Common

    写在前面: 上一篇记录了Socket聊天程序的客户端设计,为了记录的完整性,这里还是将Socket聊天的最后一个模块--Common模块记录一下.Common的设计如下: 功能说明: Common模块 ...

  6. Socket编程实践(3) 多连接服务器实现与简单P2P聊天程序例程

    SO_REUSEADDR选项 在上一篇文章的最后我们贴出了一个简单的C/S通信的例程.在该例程序中,使用"Ctrl+c"结束通信后,服务器是无法立即重启的,如果尝试重启服务器,将被 ...

  7. 网络编程应用:基于TCP协议【实现一个聊天程序】

    要求: 基于TCP协议实现一个聊天程序,客户端发送一条数据,服务器端发送一条数据 客户端代码: package Homework1; import java.io.IOException; impor ...

  8. boost asio异步读写网络聊天程序client 实例具体解释

    boost官方文档中聊天程序实例解说 数据包格式chat_message.hpp <pre name="code" class="cpp">< ...

  9. java网络编程(三):一个类似QQ的聊天程序

    客户端: package QQ; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import ...

随机推荐

  1. ecshop简单结构

    Ecshop包括的文件夹有admin.api.cert.data.images.includes.js. languages.plugins.temp.theme.wap.widget这些文件夹,和根 ...

  2. eclipse tomcat内存设置

    -Xms256M -Xmx512M -XX:PermSize=256m -XX:MaxPermSize=512m

  3. Ubuntu系统下创建python数据挖掘虚拟环境

    虚拟环境:   虚拟环境是用于创建独立的python环境,允许我们使用不同的python模块和版本,而不混淆.   让我们了解一下产品研发过程中虚拟环境的必要性,在python项目中,显然经常要使用不 ...

  4. Max Num---hdu2071

    Max Num Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  5. JSP使用JDBC ODBC 实例

    1.JDBC ODBC Brige driver是JSP连接数据库的驱动,只要安装了JDK这个驱动就默认安装了 2. 配置JDBC ODBC数据源的步骤:http://blog.csdn.net/li ...

  6. 正式学习React(一) 开始学习之前必读

    为什么要加这个必读!因为webpack本身是基于node环境的, 里面会涉及很多路径问题,我们可能对paths怎么写!webpack又是怎么找到这些paths的很迷惑. 本文是我已经写完正式学习Rea ...

  7. 做为一个Java程序员,你需要哪些傍身的技能?

    最近总有些断断续续的思考,想想从我入行以来,我到底学会了什么,做成过什么,以后要做什么,如何提升自己······· 工作3年了,常听人说3年,5年,10年是程序员的坎,每过一个都会有新的想法,新的改变 ...

  8. JavaEE Tutorials (24) - 资源适配器示例

    24.1trading示例369 24.1.1使用出站资源适配器370 24.1.2实现出站资源适配器372 24.1.3运行trading示例37324.2traffic示例374 24.2.1使用 ...

  9. [转]Geoserver实现WFS操作

    From:http://liushaobo2005.blog.163.com/blog/static/253056702011541462372/ wfs是OGC的标准规范,主要用于提供对矢量地理数据 ...

  10. [Leetcode][Python]47: Permutations II

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 47: Permutations IIhttps://oj.leetcode. ...