main.c
#include
#include
#include
#include "Server.h"
int main(int argc, char **argv)
{
int listen_socket = init();
if (-1 == listen_socket)
return;
while (1)
{
long client_socket = myAccept(listen_socket);
if (-1 == client_socket)
{
continue;
}
// 开辟线程为客户端服务
pthread_t thread;
pthread_create(&thread, NULL, handl_client, (void *)client_socket);
pthread_detach(thread); // 线程分离
}
close(listen_socket);
return 0;
}
Server.c
#include
#include /* See NOTES */
#include
#include
#include
#include
#include
#include "Server.h"
void reg(int cmd, int client_socket)
{
int result = REG_USEREXIST;
printf("客户端有一个注册请求\n");
char name[20] = {0};
char passwd[20] = {0};
int len;
read(client_socket, &len, sizeof(int)); // 读取用户名长度
read(client_socket, name, len); // 读用户名
read(client_socket, &len, sizeof(int)); // 读取密码长度
read(client_socket, passwd, len); // 密码
// 检测数据库中是否有用户,没有就将数据存入
if(0 == message_select(name))
{
result = message_add(name,passwd);
}
else
{
result = REG_USEREXIST;
}
// 告诉客户端处理的结果
write(client_socket, &cmd, sizeof(int));
write(client_socket, &result, sizeof(int));
}
void *handl_client(void *v)
{
long client_socket = (long)v;
while (1)
{
int cmd;
int ret = read(client_socket, &cmd, sizeof(int));
if (-1 == ret)
{
perror("read");
return NULL;
}
if (0 == ret)
{
break;
}
printf("从客户端收到一条消息\n");
switch(cmd)
{
case REGISTER: // 注册
reg(cmd, client_socket);
break;
case LOGIN:
break;
case QUIT:
break;
default:
printf("发生错误\n");
break;
}
}
}
// 监听套接字
int init()
{
int listen_socket = socket(AF_INET, SOCK_STREAM, 0);
if(-1 == listen_socket)
{
perror("创建套接字失败");
return -1;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET; /* Internet地址族 */
addr.sin_port = htons(PORT); /* 端口号 */
addr.sin_addr.s_addr = htonl(INADDR_ANY); /* IP地址, 绑定本地的所有ip地址*/
int ret = bind(listen_socket, (const struct sockaddr *)&addr, sizeof(addr));
if(-1 == ret)
{
perror("绑定失败");
return -1;
}
// 3、监听套接字
ret = listen(listen_socket, 5);
if(-1 == ret)
{
perror("监听失败");
return -1;
}
return listen_socket;
}
// 通信套接字
int myAccept(int listen_socket)
{
struct sockaddr_in client_addr;
socklen_t len = sizeof(client_addr);
int client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, &len);
if (-1 == client_socket)
{
perror("accept 失败");
return -1;
}
printf ("客户端的 ip = %s, 端口 = %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
return client_socket;
}
Sqlite3.c
#include
#include
#include "Server.h"
// 查询
int message_select(char *name)
{
sqlite3 *db;
int ret = sqlite3_open("message.db",&db);
if (ret != SQLITE_OK)
{
printf ("数据库打开失败\n");
return -1;
}
printf("正在查找有无重复的用户名\n");
char *errmsg;
const char *sql = "select * from message";
char **value = NULL;
int row;
int column;
ret = sqlite3_get_table(db, sql, &value, &row, &column, &errmsg);
if (ret != SQLITE_OK)
{
printf ("查询失败: %s\n", errmsg);
sqlite3_free(errmsg);
return -1;
}
int i;
for (i = column; i < row*column; i += column)
{
if(0 == strcmp(value[i],name))
{
printf("用户名已被注册\n");
return 1;
}
}
printf("%s还没有被注册\n",name);
sqlite3_free_table(value); // 释放查询结果
sqlite3_close(db);
return 0;
}
//创建添加
int message_add(char *name, char *passwd)
{
printf("正在注册......");
//创建文件
sqlite3 *db;
int ret = sqlite3_open("message.db",&db);
if (ret != SQLITE_OK)
{
printf ("数据库打开失败\n");
return -1;
}
//创建表
char *errmsg;
const char *sql = "create table if not exists message(Name TEXT,Passwd TEXT, primary key(name))";
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg );
if (ret != SQLITE_OK)
{
printf ("exec 失败: %s\n", errmsg);
return -1;
}
char str[100];
sprintf (str, "insert into message values('%s', '%s')", name, passwd);
ret = sqlite3_exec(db, str, NULL, NULL, &errmsg );
if (ret != SQLITE_OK)
{
printf ("exec 失败: %s\n", errmsg);
return REG_USEREXIST;
}
sqlite3_close(db);
return REG_OK;
}
#include
#include
#include
#include
#include
#include /* See NOTES */
#include
#include "Client.h"
int main(int argc, char **argv)
{
// 1、创建套接字
// 第一个参数:使用的协议族
// 第二个参数:使用的协议类型
// 第三个参数:一般写 0
int conn_socket = socket(AF_INET, SOCK_STREAM, 0);
if(-1 == conn_socket)
{
perror("创建套接字失败");
return -1;
}
//2、连接服务器
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET; /* Internet地址族 */
addr.sin_port = htons(atoi(argv[2])); /* 端口号 */
addr.sin_addr.s_addr = inet_addr(argv[1]); /* IP地址, 绑定本地的所有ip地址*/
//绑定服务器的 ip 地址和端口
int ret = connect(conn_socket, (const struct sockaddr *)&addr, sizeof(addr));
if(-1 == ret)
{
perror("连接服务器失败");
return -1;
}
pthread_t thread;
pthread_create(&thread , NULL, write_data, (void *)&conn_socket);
read_data(conn_socket);
close(conn_socket);
return 0;
}
Client.c
#include
#include /* See NOTES */
#include
#include
#include
#include
#include
#include "Client.h"
void write_reg(int client_socket)
{
//命令
int cmd = 1;
//用户名/密码长度
int len;
//用户名
char name[20] = {0};
//密码
char passwd[20] = {0};
//一开始将cmd写入
write(client_socket, &cmd, sizeof(int));
//填写用户名,并测量用户名长度
printf("请输入用户名\n");
scanf("%s", name);
len = strlen(name);
//先将用户名长度填入
write(client_socket, &len, sizeof(int));
//再将用户名填入
write(client_socket, name, len);
//填写密码,并测量密码长度
printf("请输入密码\n");
scanf("%s", passwd);
len = strlen(passwd);
//先将密码长度填入
write(client_socket, &len, sizeof(int));
//再将密码填入
write(client_socket, passwd, len);
return;
}
//子线程负责往服务器写数据
void *write_data(void *v)
{
system("clear");
int client_socket = *(int*)v;
int cmd;
while(1)
{
sleep(2);
printf("1、注册\n");
printf("2、登陆\n");
printf("3、退出\n");
printf("请输入指令:");
scanf("%d",&cmd);
switch(cmd)
{
case REGISTER:
write_reg(client_socket);
break;
case LOGIN:
break;
case QUIT:
break;
default:
printf("输入错误,请重新输入\n");
break;
}
}
}
void read_reg(int client_socket)
{
int result;
int ret = read(client_socket, &result, sizeof(int));
if (-1 == ret)
{
perror ("read error");
}
switch(result)
{
case REG_OK:
printf("注册成功\n");
break;
case REG_USEREXIST:
printf("用户已存在,注册失败,请重新注册\n");
break;
default:
printf("出现错误,请重新注册\n");
break;
}
}
//主线程负责从服务器读数据
void read_data(int client_socket)
{
int cmd;
while (1)
{
int ret = read(client_socket, &cmd, sizeof(int));
if (-1 == ret)
{
perror ("read error");
}
if (0 == ret)
{
printf ("客户端退出\n");
break;
}
system("clear");
switch(cmd)
{
case REGISTER:
read_reg(client_socket);
break;
case LOGIN:
break;
case QUIT:
break;
default:
printf("读取错误,请重新输入\n");
break;
}
}
}