聊天室项目

  • Post author:
  • Post category:其他


1、简述:

采用了cs结构

服务器端四步走:socket,bind,listen,accept

客户端两步走:socket,connect

简单模型:客户端a消息发送到服务器;服务器找到客户端b的socket,在把消息发送给客户端b;

设计数据库操作存储的一些操作比较简单这里不提

2、看代码:

(1)、服务器端代码

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sqlite3.h>


#define PORT  9999

struct User
{
    char name[20];   // 用户名
    int  socket;     // 和用户通信的socket
};



// 协议
struct Msg
{
    char information[1024]; //发送消息
    char msg[1024];  // (姓名)消息内容

    int id;
    char sex[20];
    int age;
    int password;

    char toname[20];
    char fromname[20];
    int  cmd;        // 消息类型

    char online_name[20]; //在线姓名;
};

struct User user[2000] = {0};


//打开数据库函数,客户端用户登录数据传递过来,服务器端打开数据库比较查询是否匹配此登录用户信息;
int Database_enter(int client_socket,struct Msg *msg)
{
    sqlite3 *database;
    int ret = sqlite3_open( "information.db", &database );
    if(ret != SQLITE_OK)
    {
        perror("sqlite3_open");
        return -1;
    }
    printf("数据库打开成功\n");


    // 3、char ***resultp: char *resultp[] = {"id", "name", "sex", "age", "1", "zhang", "M", "12","2".....};
    // 4、nrow: 多少行数据
    // 5、ncolumn: 多少列数据
    char ** resultp;
    char *errmsg = NULL;
    int nrow;
    int ncolumn;
    //进行什么操作;
    char *sql = "select * from information";

    ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg );

    if(ret != SQLITE_OK)
    {
        printf("数据库操作失败 %s\n",errmsg);
        return -1;
    }

    //查询之后,把客户端传递过来的数据和这张表里的数据想比较,先比较唯一的name;再比较password;
    int i;
    for(i = 0 ;i < (nrow+1)*ncolumn;i++)
    {
        if (strncmp (resultp[i],msg->msg,strlen(msg->msg)) == 0)
        //if (strncmp (resultp[i],msg->msg,strlen(msg->msg)-1) == 0)
        {
            if(atoi(resultp[i+1]) == msg->password) //强制转换;
            {
                printf("服务器端已经通过登录验证\n");
                msg->cmd = 1002;

                int k;
                for(k = 0 ;k < 2000; k++)
                {
                    if(user[k].socket == 0)
                    {
                        strcpy(user[k].name, msg->msg);
                        user[k].socket = client_socket;
                        printf("名字:%s\n",user[k].name);
                        break;
                    }
                }

                break;
            }
            else
            {
                printf("服务器端发现你的密码不正确哦!\n");
                msg->cmd = -1;
                break;
            }
        }
    }
    if(i == (nrow+1)*ncolumn)
    {
        msg->cmd = -2;
        printf("服务器端没找到该用户\n");
    }


    sqlite3_free_table(resultp);  //之前的char**resultp (数组)等于malloc了一个空间来储存数据库的数据;所以需要释放;
    sqlite3_close(database);
    printf("%d,%d\n",msg->cmd,sizeof(msg));
}

//私聊数据库函数
int Database_chat2(int client_socket,struct Msg *msg)
{
    sqlite3 *database;
    int ret = sqlite3_open( "information.db", &database );
    if(ret != SQLITE_OK)
    {
        perror("sqlite3_open");
        return -1;
    }
    printf("数据库打开成功\n");


    // 3、char ***resultp: char *resultp[] = {"id", "name", "sex", "age", "1", "zhang", "M", "12","2".....};
    // 4、nrow: 多少行数据
    // 5、ncolumn: 多少列数据
    char ** resultp = NULL;
    char *errmsg = NULL;
    int nrow;
    int ncolumn;
    //进行什么操作;
    char *sql = "select * from information";

    ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg );

    if(ret != SQLITE_OK)
    {
        printf("数据库操作失败 %s\n",errmsg);
        return -1;
    }

    //查询之后,把客户端传递过来的数据和这张表里的数据想比较,先比较唯一的name;再比较password;
    int i;
    for(i = 0 ;i < (nrow+1)*ncolumn;i++)
    {
        if (strncmp (resultp[i],msg->toname,strlen(msg->toname)) == 0)
        //  if (strncmp (resultp[i],msg->toname,strlen(msg->toname)-1) == 0)
        {
            printf("222222\n");
            msg->cmd = 11;
            return 11;
        }
    }

    if(i == (nrow+1)*ncolumn)
    {
        msg->cmd = -5;
        return -5;
    }

    sqlite3_free_table(resultp);  //之前的char**resultp (数组)等于malloc了一个空间来储存数据库的数据;所以需要释放;
    sqlite3_close(database);


}

//数据库写入注册数据函数
int Database_insert( struct Msg *msg)
{
    sqlite3 *database;

    //打开数据库,数据库指针指向你要打开的数据库,studtet.db是你创建的数据库文件

    int ret = sqlite3_open( "information.db", &database );
    if(ret != SQLITE_OK)
    {
        perror("sqlite3_open");
        return -1;
    }
    printf("数据库打开成功\n");

    //下边一大段是创建一个表
    char *errmsg = NULL;

    //sql语句
    char *sql = "create table if not exists information (name TEXT, PASSWORD INTEGER, primary key(name))";    

    //执行sql语句的函数;
    ret = sqlite3_exec(database ,sql, NULL ,NULL ,&errmsg);
    if(ret != SQLITE_OK)
    {
        printf("数据库创建操作失败 %s\n",errmsg);
        return -1;
    }

    //往表里边插入数据;
    //insert into student values(1, 'Zhang', 'M', 18);

    char buf[100];
    sprintf(buf," insert into information values('%s',%d)",msg->msg ,msg->password );
    //设置主键之后,如果插入的id已经存在那么就会返回错误,一班来说返回的错误都是插入重复这里有点取巧;
    ret = sqlite3_exec(database ,buf, NULL ,NULL ,&errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库插入操作失败:%s\n", errmsg);
        return -2;
    }
    printf("数据库已经成功插入了你的注册信息\n");
    sqlite3_close(database);
    return 1;
}


// 初始化套接字,返回监听套接字
int init_socket()
{
        //1、创建socket
    int listen_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (listen_socket == -1)
    {
        perror ("socket");
        return -1;
    }

    // 2、命名套接字,绑定本地的ip地址和端口
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family  = AF_INET;     // 设置地址族
    addr.sin_port    = htons(PORT); // 设置本地端口
    addr.sin_addr.s_addr = htonl(INADDR_ANY);   // 使用本地的任意IP地址

    int  ret = bind(listen_socket,  (struct sockaddr *)&addr, sizeof(addr));
    if (ret == -1)
    {
        perror ("bind");
        return -1;
    }

    // 3、监听本地套接字
    ret = listen(listen_socket, 5);
    if (ret == -1)
    {
        perror ("listen");
        return -1;
    }

    printf ("等待客户端连接.......\n");
    return listen_socket;
}

// 处理客户端连接,返回与连接上的客户端通信的套接字
int  MyAccept(int listen_socket)
{
    // 4、接收连接
    // 监听套接字不能用来与客户端进行通信,它的职责是监听客户端的连接
    // accpet 处理客户端的连接,如果成功接收,会返回一个新的套接字,用来与客户端进行通信
    // accept的第三个参数 是一个传入传出参数
    struct sockaddr_in client_addr; // 用来保存客户端的ip和端口信息
    int len = sizeof(client_addr);
    int client_socket = accept(listen_socket,   (struct sockaddr *)&client_addr,  &len);
    if (client_socket == -1)
    {
        perror ("accept");
    }

    printf ("成功接收一个客户端: %s\n", inet_ntoa(client_addr.sin_addr));

    return client_socket;
}


//注册函数
void reg(int client_socket, struct Msg *msg)
{
    printf ("%s 正在进行注册\n", msg->msg);

    //下边的代码就是应该把注册的消息写进数据库;
    int ret = Database_insert( msg );
    if(ret == -2)
    {
        printf("该用户id已经被注册 \n");
        msg->cmd = -2;
    }
    else
    {
        msg->cmd = 1001;
    }
    //msg->cmd = 1001;
    /* {
        // 将用户套接字进行保存,保存在数组里
        int i = 0;
        for (i = 0; i < 20; i++)
        {
            if (user[i].socket == 0)
            {
                strcpy (user[i].name , msg->msg);
                user[i].socket = client_socket;
                break;
            }
        }

        if (i == 2000)
        {
            msg->cmd = -1;
        }
        else
        {
            msg->cmd = 1001;
        }
    }
     */

    write (client_socket, msg, sizeof(struct Msg));
}



//登录验证函数;
 void enter(int client_socket, struct Msg *msg)
 {
    Database_enter(client_socket,msg );
    write(client_socket, msg ,sizeof(struct Msg));
    printf("11111111\n");
 }



// 群发
void chat(int client_socket, struct Msg *msg)
{
    printf ("%s 发一次群消息\n", msg->msg);

    // 将用户进行保存
    int i = 0;
    for (i = 0; i < 2000; i++)
    {
        if (user[i].socket != 0)
        {
            write (user[i].socket, msg, sizeof(struct Msg));    
        }
    }
}

// 私聊
void chat2(int client_socket, struct Msg *msg)
{
    printf ("%s 要 给 %s 发一条消息\n", msg->fromname, msg->toname);

    //判断数据库是够有此用户
    int ret  = Database_chat2(client_socket,msg);
    if(ret == -5)
    {
        printf("此用户不存在\n");
        write(client_socket,msg,sizeof(struct Msg));
    }
    //用户才在于数据库,查找是否在线?
    else if(ret == 11)
    {
        printf("数据库存在此用户,正在判断该用户是否在线\n");

        //判断用户是否在线;
        int i = 0;
        for (i = 0; i < 2000; i++)
        {
            if (user[i].socket != 0 && strncmp(user[i].name, msg->toname,strlen(msg->toname))==0)
            //  if (user[i].socket != 0 && strncmp(user[i].name, msg->toname,strlen(msg->toname)-1)==0)
            {
                printf("11111111\n");
                msg->cmd = 10;
                write(client_socket,msg,sizeof(struct Msg));
                printf("服务器判断出该用户在线,正在给该用户发送消息....\n");
                msg->cmd = 3;
                write (user[i].socket, msg, sizeof(struct Msg));
                printf("1111111111\n");
                break;
            }
        }

        if(i == 2000)
        {
            printf("服务器显示该用户不在线\n");
            msg->cmd = -6;
            write(client_socket,msg,sizeof(struct Msg));

        }
    }


}


//显示在线好友列表;
void display(int client_socket,struct Msg *msg)
{
    //服务器端把user[]里边的在线遍历出来发送给客户端;
    int i;
    msg->cmd = 4;
    for(i = 0;i < 2000;i++)
    {
        if(user[i].socket != 0)
        {
            //遍历一次写给客户端一次;
            strncpy(msg->online_name ,user[i].name,strlen(user[i].name));
            write(client_socket, msg ,sizeof(struct Msg));
            printf("44444444\n");
        }
    }

}

//注销用户信息
int logout(int client_socket, struct Msg *msg)
{


    sqlite3 * database;

    // 打开数据库
    int ret = sqlite3_open("information.db", &database);
    if (ret != SQLITE_OK)
    {
        printf ("打开数据库失败\n");
        return -1;
    }
    printf ("打开数据库成功\n");

    char *errmsg = NULL;
    char buf[100];
    sprintf (buf, "delete from information where name = '%s'", msg->msg);
    ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return -1;
    }

    printf("注销成功\n");

    write(client_socket,msg, sizeof(struct Msg));
    printf("msg.cmd %d\n",msg->cmd);
    sqlite3_close(database);
}


// 把 负责处理客户端通信的函数改成线程的工作函数
void* hanld_client(void* v)
{
    int client_socket = (int)v;
    struct Msg msg;
    while(1)
    {
        // 从客户端读一个结构体数据
        int ret = read(client_socket, &msg, sizeof(msg));
        //printf("2:%d,%d\n",msg.cmd,sizeof(msg));
        if (ret == -1)
        {
            perror ("read");
            break;
        }

        // 代表客户端退出
        if (ret == 0)
        {
            printf ("客户端退出\n");
            break;
        }


        switch (msg.cmd)
        {
            case 1 :    // 客户但进行注册
                reg(client_socket, &msg);
                break;
            case 2 :    // 客户端进行群聊天
                chat(client_socket, &msg);
                break;
            case 3 :    // 客户端进行私聊
                chat2(client_socket, &msg);
                break;

            case 4:   //客户进行登录;
                enter(client_socket,&msg);
                break;

            case 5: //显示在线好友列表;
                display(client_socket,&msg);
                break;

            case 6: //注销用户;
                logout(client_socket,&msg);
                break;
        }

    }


    close (client_socket);
}

int main() 
{
    // 初始化套接字
    int listen_socket = init_socket();

    while (1)
    {
            // 获取与客户端连接的套接字
        int client_socket = MyAccept(listen_socket);

        // 创建一个线程去处理客户端的请求,主线程依然负责监听
        pthread_t id;
        pthread_create(&id, NULL, hanld_client,  (void *)client_socket);

        pthread_detach(id); // 线程分离
    }
    close (listen_socket);

    return 0;
}

(2)、客户端代码

这里写代码片#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sqlite3.h> 

#define PORT  9999
void enter( int );

char myName[20];
char Sex[20];

struct Msg
{
    char information[1024]; //发送消息;
    char msg[1024];  // (姓名)消息内容
    int id;
    char sex[20];
    int age;
    int password;

    char toname[20];  //消息发给谁
    char fromname[20]; //消息从谁的那边发出来
    int  cmd;        // 消息类型

    char online_name[20]; //在线姓名;
};


// 主界面;
void interface()
{
    printf ("\t\t 1、注册\n");
    printf ("\t\t 2、登录\n");

}

void interface3()
{
    //printf ("\t\t 1、注册\n");
    printf ("\t\t 2、登录\n");

}



 //登录后的界面;
void interface2()
{
    printf ("\t\t 1、发送文件\n");
    printf ("\t\t 2、群聊\n");
    printf ("\t\t 3、私聊\n");
    printf ("\t\t 4、注销当前用户\n");
    printf ("\t\t 5、显示好友列表\n");
    printf ("\t\t 6、查看本地聊天记录\n");
}

//读写分离的读线程的回调函数;
 void * readMsg(void *v)
 {
     int socketfd = (int)v;
     struct Msg msg;
     while (1)
     {
         read(socketfd, &msg, sizeof(msg));
         //printf("test msg.cmd %d,%d\n",msg.cmd,sizeof(msg));
         switch (msg.cmd)
         {
             case -5:  //私聊用户不存在;
                printf("你想私聊的用户不存在\n");
                break;

             case 10:   //用户存在并且在线;
                printf("用户存在并且在线\n");
                break;

            case -6: //用户不在线;
                printf("用户存在但是不在线\n");
                break;

             case 2:   // 群聊
                printf ("收到一条消息: %s\n", msg.information);
                break;

             case 3:   // 私聊
                printf ("%s 给你发一条消息:%s\n", msg.fromname, msg.information);
                break;

             case 4:   // 显示在线好友列表;
                printf("在线的好友有:%s\n",msg.online_name);
                printf("3333333\n");
                break;

            case 6: //用户注销;
                printf("注销成功!\n");
                return;
                break;
         }

     }
 }


 //注册函数
int reg(int socketfd)
{
    struct Msg msg;
    //msg.cmd = 1;

    while(1)
    {
        msg.cmd = 1;

        //memset(&msg,0,sizeof(msg));//清零
        printf ("请输入用户名:\n");
        scanf("%s",&(msg.msg));

        printf ("请输入用户的密码 :\n");
        scanf("%d",&(msg.password));


        write (socketfd, &msg, sizeof(msg));

        //来自服务器端的回复:到底有没有注册成功,成功了返回一个标号,要是失败了,那么为什么失败,返回另外一个标号,最后失败的需要全部重新注册

        read (socketfd, &msg, sizeof(msg));

        if (msg.cmd == 1001)
        {
            printf ("你已注册成功,欢迎加入聊天室\n");

            /* int a;
            while (1)
            {
                printf("\n");
                interface3();
                printf("\n");
                printf("\n");
                sleep(1);
                printf("\t\t*_*输入功能:\n");
                scanf("%d",&a);
                printf("\n");
                while(getchar()!= '\n');
                switch(a)
                {
                    case 2:     //登录;
                        enter(socketfd);
                        break;

                }

                system("clear");
            }
            */





            break;
        }
        //用户已经被注册过了,重新注册

        if (msg.cmd == -2)
        {
            printf ("该用户名已经被注册,请重新进行注册\n");
            memset(&msg,0,sizeof(msg));//清零
            continue;
        }
        //聊天室的登录人数上限已经到达注册失败;
        else if(msg.cmd == -1)
        {
            printf ("聊天室的上限已经到达,请重新进行注册\n");
            continue;
        }

    }

    sleep(1);




}


 //群聊函数,
void chat(int socketfd)
{
    struct Msg msg;
    msg.cmd = 2;
    printf ("请输入要发送的内容: \n");
    //fgets(msg.information, 1024, stdin);
    scanf("%s",msg.information);
    write (socketfd, &msg, sizeof(msg));
}


 //私聊;
void chat2(int socketfd)
{
    struct Msg msg;
    msg.cmd = 3;
    printf ("请输入要发送的对象名称: \n");
    //fgets(msg.toname, 20, stdin);
    scanf("%s",msg.toname);

    printf ("请输入要发送的内容: \n");
    //fgets(msg.information, 1024, stdin);
    scanf("%s",msg.information);

    printf("输入自己的名字 : \n");
    //fgets(msg.fromname, 20, stdin);
    scanf("%s",msg.fromname);

    write (socketfd, &msg, sizeof(msg));

     //调用存储聊天记录的函数;
    int ret = insert_msg( &msg );
    if(ret == 1)
    {
        printf("成功保存本地记录\n");
    } 
}


 //注销用户;
void logout(int socketfd)
{
    char ch[2];
    printf("是否注销此用户: y/n \n");
    scanf("%c",ch);
    if(ch[0] == 'y')
    {
        struct Msg msg;
        msg.cmd = 6;
        printf("输入您的用户名:\n");
        scanf("%s",msg.msg);

        write(socketfd, &msg,sizeof(struct Msg)); 
    }
    else
    {
        return ;
    }


}


//显示在线好友列表;
void display(int socketfd)
{
    struct Msg msg;
    printf("我想知道在线的好友列表\n");
    msg.cmd = 5;
    write(socketfd, &msg, sizeof(struct Msg)); 
}  


//登录函数;
void enter(int socketfd)
{
    struct Msg msg;
    msg.cmd = 4;
    printf("请输入用户名 :\n");
    scanf("%s",&(msg.msg));

    printf("请输入用户密码:\n");
    scanf("%d",&(msg.password));

    write (socketfd, &msg, sizeof(msg)); //消息写过去,等待回复,例如什么用户不存在,密码错误;
    if(msg.cmd == 5)
    {

    }
    read(socketfd ,&msg ,sizeof(msg)); //读取来自服务器的返回的消息,进行客户端屏幕打印;
    //printf("%d,%d\n",msg.cmd,sizeof(msg));
    if(msg.cmd == 1002)
    {
        printf("恭喜你登录成功\n");


        //登录完成之后开始读写分离;
        sleep(1);

        pthread_t id;
        pthread_create(&id, NULL, readMsg,  (void *)socketfd);

        pthread_detach(id); // 线程分离 


        int a;
        while (1)
        {
            interface2();
            printf("\n");
            printf("\n");
            sleep(1);
            printf("\t\t*_*输入功能:\n");
            scanf("%d",&a);
            printf("\n");
            while(getchar()!= '\n');
            switch(a)
            {

                case 1:   //发送文件
                    send_file(socketfd);
                    break;
                case 2:     // 群聊天
                    chat(socketfd);
                    break;
                case 3:     // 私聊
                    chat2(socketfd);
                    break;
                case 4 :   //注销用户;
                    logout(socketfd);
                    return;
                case 5:  //显示在线好友列表;
                    display(socketfd);
                    sleep(1);
                    break;

                case 6: //查看本地聊天记录;
                    look_msg(socketfd);
                    sleep(1);
                    break;

            }

            system("clear");
        }


    }
    else if(msg.cmd == -1)
    {
        printf("密码不正确\n");
        usleep(5*100000);
    }
    else if(msg.cmd == -2)
    {
        printf("该用户不存在\n");
        sleep(0.5);
    }



 }


//聊天记录存到本地;
int insert_msg(struct Msg* msg)
{    
    sqlite3 *database;
    int ret = sqlite3_open( "msg.db", &database );
    if(ret != SQLITE_OK)
    {
        perror("sqlite3_open");
        return -1;
    }
    printf("数据库打开成功\n"); 

    //下边一大段是创建一个表
    char *errmsg = NULL;
    char *sql = "create table if not exists msg (fromname TEXT, information TEXT,toname TEXT)";     //sql语句   
    ret = sqlite3_exec(database ,sql, NULL ,NULL ,&errmsg);//执行sql语句的函数;
    if(ret != SQLITE_OK)
    {
        printf("数据库创建操作失败 %s\n",errmsg);
        return -1;
    }

    //往表插入数据;
    //insert into student values(1, 'Zhang', 'M', 18);
    char buf[100];
    printf("%s\n",msg->fromname);
    sprintf(buf," insert into msg values('%s','%s' ,'%s')",msg->fromname ,msg->information ,msg->toname );
    //设置主键之后,如果插入的id已经存在那么就会返回错误,一班来说返回的错误都是插入重复这里有点取巧;
    ret = sqlite3_exec(database ,buf, NULL ,NULL ,&errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库插入操作失败:%s\n", errmsg);
        return -1;
    }
    printf("聊天记录成功保存到本地数据库*_*\n");
    sqlite3_close(database);
    return 1;
}

//查看本地聊天记录;
int look_msg(int socketfd)
{
    //本地创建一张数据库表,存放本地的消息;
    //查看不就简单了,直接打开本地的数据库就好了;
    sqlite3 *database;
    int ret = sqlite3_open( "msg.db", &database );
    if(ret != SQLITE_OK)
    {
        perror("sqlite3_open");
        return -1;
    }
    printf("数据库打开成功\n"); 

    char ** resultp;
    char *errmsg = NULL;
    int nrow;
    int ncolumn;
    //进行什么操作;
    char *sql = "select * from msg";

    ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg );

    if(ret != SQLITE_OK)
    {
        printf("数据库操作失败 %s\n",errmsg);
        return -1;
    }

    int i;
    printf("nrow = %d,ncolumn = %d",nrow, ncolumn);
    for(i = 0; i < (nrow +1)* ncolumn;i++)
    {
        if(i % ncolumn == 0)
        {
            printf("\n");
        }
        printf("%-18s" ,resultp[i]);
    }
    printf("\n");

    sqlite3_free_table(resultp);  //之前的char**resultp (数组)等于malloc了一个空间来储存数据库的数据;所以需要释放;
    sqlite3_close(database);
}


//传送文件;
send_file(int socketfd)
{

 }


// 客户端向服务器发送数据处理函数;
void ask_server(int socketfd)
{
    int a ;
    while (1)
    {

        //char ch[2];
        int a;
        while (1)
        {
            printf("\n");
            interface();
            printf("\n");
            printf("\n");
            sleep(1);
            printf("\t\t*_*输入功能:\n");
            scanf("%d",&a);
            printf("\n");
            while(getchar()!= '\n');
            switch(a)
            {
                case 1:     //注册;
                    reg(socketfd);
                    printf("注册注册注册\n");
                    break;
                case 2:     //登录;
                    enter(socketfd);
                    break;

            }

            system("clear");
        }
    }
}


int main()
{   
    // 创建与服务器通信的套接字
    int socketfd = socket(AF_INET, SOCK_STREAM, 0);
    if (socketfd == -1)
    {
        perror ("socket");
        return -1;
    }

    // 连接服务器
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family  = AF_INET;     // 设置地址族
    addr.sin_port    = htons(PORT); // 设置本地端口
    inet_aton("127.0.0.1",&(addr.sin_addr));


    // 连接服务器,如果成功,返回0,如果失败,返回-1
    // 成功的情况下,可以通过socketfd与服务器进行通信
    int ret = connect(socketfd, (struct sockaddr *)&addr, sizeof(addr));
    if (ret == -1)
    {
        perror ("connect");
        return -1;
    }

    printf ("成功连上服务器\n");

    //开始进行操作;


    ask_server(socketfd);

    // 关闭套接字
    close(socketfd);

    return 0;
}



版权声明:本文为Janskid原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。