這個簡單的通訊系統使用 C 語言完成編寫,採用 C/S 架構,在 Linux 平臺下,運用到 TCP/IP 協議,多線程編程的技術,使用幾個簡單 API 對 sqlite3 數據庫進行操作,能實現註冊,登錄,羣聊,私聊等幾種功能。
下面是程序代碼:
服務器端:
#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>
#include <stdlib.h>
#define PORT 9999
#define FALSE 0
#define TRUE 1
typedef struct Log_msg
{
char name[20];
int socket;
}log_msg;
typedef log_msg LinkData;
typedef struct _node
{
LinkData data;
struct _node *next;
}Node;
Node *head;
struct Msg
{
int len;
int a[20];
char msg[1024];
char name[20];
char password[20];
char guys[100];
char toname[20];
char fromname[20];
char quitname[20];
char logoutname[20];
char sign[20];
int cmd;
};
//創建鏈表
Node * Create_List()
{
Node *list = (Node*)malloc(sizeof(Node)/sizeof(char));
if (list == NULL)
return NULL;
list->next = NULL; // 空表
return list;
}
//尾插
int Insert_Last(Node *h, LinkData data)
{
if (h == NULL)
return FALSE;
Node *node = (Node*)malloc(sizeof(Node)/sizeof(char));
if (node == NULL)
{
return FALSE;
}
node->data = data;
node->next = NULL;
Node* tmp = h;
while (tmp->next)
{
tmp = tmp->next;
}
tmp->next = node;
return TRUE;
}
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 = htons(INADDR_ANY);
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 Accept(int listen_socket)
{
//4.接收連接
struct sockaddr_in client_addr;
int len = sizeof(client_addr);
int client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, &len);
if(client_socket == -1)
{
perror("accept");
return -1;
}
printf("成功接收了一個客戶端:%s\n", inet_ntoa(client_addr.sin_addr));
return client_socket;
}
int reg(int client_socket, struct Msg *msg)//註冊操作
{
printf("%s進行註冊\n", msg->name);
//打開數據庫chatroom
sqlite3 *db;
int ret = sqlite3_open("chatroom.db", &db);
if(ret != SQLITE_OK)
{
printf("打開數據庫失敗\n");
return -1;
}
printf("打開數據庫成功\n");
//創建一張表login,用於存放用戶的信息
char *errmsg = NULL;
char *sql = "create table if not exists login(name TEXT, password TEXT, sign TEXT, primary key(name))";
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("數據庫操作失敗:%s\n", errmsg);
return -1;
}
char buf[100];
//將從客戶端收來的信息存放到數據庫中
sprintf(buf, "insert into login values('%s', '%s', '%s')", msg->name, msg->password, msg->sign);
ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("數據庫操作失敗:%s\n", errmsg);
msg->cmd = -1;
return -1;
}
else
{
printf("插入信息成功\n");
msg->cmd = 1001;
}
//反饋結果給客戶端
write (client_socket, msg, sizeof(struct Msg));
sqlite3_close(db);
return 0;
}
int login(int client_socket, struct Msg *msg)//登錄操作
{
printf("%s正在進行登錄\n", msg->name);
//打開數據庫chatroom
sqlite3 *db;
int ret = sqlite3_open("chatroom.db", &db);
if(ret != SQLITE_OK)
{
printf("打開數據庫失敗\n");
return -1;
}
printf("打開數據庫成功\n");
char *errmsg = NULL;
char **resultp, **resultl;
int nrow, ncolumn, lrow, lcolumn;
char buf[100];
char ptr[100];
sprintf(buf, "select password from login where name = '%s'", msg->name);
//在數據庫中找出與傳過來name對應的password
ret = sqlite3_get_table(db, buf, &resultp, &nrow, &ncolumn, &errmsg);
if(ret != SQLITE_OK)
{
printf("數據庫操作失敗:%s\n", errmsg);
return -1;
msg->cmd = -1;
}
sprintf(ptr, "select * from login where name = '%s'", msg->name);
// char *sql = "select name from login";
//在數據庫中找出與傳過來name對應的password
ret = sqlite3_get_table(db, ptr, &resultl, &lrow, &lcolumn, &errmsg);
if(lrow == 0)
{
printf("不存在\n");
// return -1;
msg->cmd = -2;
write (client_socket, msg, sizeof(struct Msg));
return -1;
printf("不存在\n");
}
// int i;
// char *t;
// head = Create_List();
Node *node = (Node*)malloc(sizeof(Node)/sizeof(char));
if(strcmp(resultp[1], msg->password) != 0)
{
// printf("驗證失敗\n");
msg->cmd = -1;
printf("%d\n", msg->cmd);
printf("驗證失敗\n");
}
else
{
printf("驗證成功\n");
msg->cmd = 1002;
//登錄成功後將登陸成功者的姓名和套接字存到鏈表head中
// printf("%s\n", msg->name);
node->data.socket = client_socket;
strcpy(node->data.name, msg->name);
// printf("%s\n", node->data.name);
Insert_Last(head, node->data);
}
Node *tmp = head->next;
while(tmp)
{
printf("插入鏈表姓名:%s\n", tmp->data.name);
printf("插入鏈表套接字:%d\n", tmp->data.socket);
tmp = tmp->next;
}
write (client_socket, msg, sizeof(struct Msg));
sqlite3_close(db);
return 0;
}
int Display(int client_socket, struct Msg *msg)//展示在線人員
{
// char a[20];
// strcpy(msg->msg, a);
printf("測試:%d\n", msg->len);
Node *tmp = head->next;
int len = 0;
while(tmp)
{
len++;
tmp = tmp->next;
}
//求鏈表長度
printf("長度:%d\n", len);
//找出鏈表中的數據
tmp = head->next;
int i = 0;
while(i < len)
{
//strcpy(msg->guys[i],tmp->data.name);
msg->a[i] = tmp->data.socket;
strcpy(msg->guys,tmp->data.name);
tmp = tmp->next;
i++;
printf("套接字:%d\n", msg->a[0]);
printf("姓名:%s\n", msg->guys);
write (client_socket, msg, sizeof(struct Msg));
}
// msg->len = len;
// write (client_socket, msg, sizeof(struct Msg));
}
int group_chat(int client_socket, struct Msg *msg)//羣聊
{
Node *tmp = head->next;
while(tmp)
{
write(tmp->data.socket, msg, sizeof(struct Msg));
tmp = tmp->next;
}
}
int private_chat(int client_socket, struct Msg *msg)//私聊
{
printf("%s 要給%s 發一條消息\n", msg->fromname, msg->toname);
// && (strcmp(tmp->data.name, msg->toname) == 0)
Node *tmp = head->next;
while(tmp != NULL)
{
printf("11111111111111\n");
if(strncmp(tmp->data.name, msg->toname,strlen(msg->toname) - 1) == 0)
{
write(tmp->data.socket, msg, sizeof(struct Msg));
printf("套接字%d\n", tmp->data.socket);
printf("11222222222221\n");
}
tmp = tmp->next;
}
}
int Quit(int client_socket, struct Msg *msg)//退出登錄
{
printf("姓名:%s\n", msg->quitname);
Node *tmp = head;
while(tmp->next)
{
printf("222222222\n");
if(strcmp(tmp->next->data.name, msg->quitname) == 0)
break;
tmp = tmp->next;
}
// if(tmp->next == NULL);
// return FALSE;
// printf("鏈表中姓名:%s\n", tmp->next->data.name);
Node *p = tmp->next;
tmp->next = p->next;
free(p);
// msg->cmd = 1006;
printf("222222222\n");
tmp = head->next;
while(tmp)
{
printf("鏈表中姓名:%s\n", tmp->data.name);
printf("鏈表中套接字:%d\n", tmp->data.socket);
tmp = tmp->next;
}
write (client_socket, msg, sizeof(struct Msg));
return TRUE;
}
int logout(int client_socket, struct Msg *msg)//註銷用戶
{
printf("註銷姓名%s\n", msg->logoutname);
sqlite3 *db;
int ret = sqlite3_open("chatroom.db", &db);
if(ret != SQLITE_OK)
{
printf("打開數據庫失敗\n");
return -1;
}
printf("打開數據庫成功\n");
char *errmsg = NULL;
char buf[100];
sprintf(buf, "delete from login where name = '%s'", msg->logoutname);
ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("數據庫操作失敗:%s\n", errmsg);
return -1;
}
else
{
printf("註銷成功\n");
msg->cmd = 1007;
}
write (client_socket, msg, sizeof(struct Msg));
sqlite3_close(db);
return 0;
}
int signature(int client_socket, struct Msg *msg)//展示簽名
{
sqlite3 *db;
int ret = sqlite3_open("chatroom.db", &db);
if(ret != SQLITE_OK)
{
printf("打開數據庫失敗\n");
return -1;
}
printf("打開數據庫成功\n");
char *errmsg = NULL;
char **resultp;
int nrow, ncolumn;
char buf[100];
sprintf(buf, "select sign from login where name = '%s'", msg->name);
//在數據庫中找出與傳過來name對應的password
ret = sqlite3_get_table(db, buf, &resultp, &nrow, &ncolumn, &errmsg);
if (ret != SQLITE_OK)
{
printf ("數據庫操作失敗:%s\n", errmsg);
return -1;
}
strcpy(msg->sign, resultp[1]);
write (client_socket, msg, sizeof(struct Msg));
sqlite3_close(db);
return 0;
}
int change_sign(int client_socket, struct Msg *msg)//修改個性簽名
{
sqlite3 *db;
int ret = sqlite3_open("chatroom.db", &db);
if(ret != SQLITE_OK)
{
printf("打開數據庫失敗\n");
return -1;
}
printf("打開數據庫成功\n");
char buf[100];
char *errmsg = NULL;
//改寫數據庫中的簽名
sprintf(buf, "update login set sign = '%s' where name = '%s'", msg->sign, msg->name);
ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("數據庫操作失敗:%s\n", errmsg);
msg->cmd = -1;
return -1;
}
else
{
printf("修改信息成功\n");
msg->cmd = 1008;
}
//反饋結果給客戶端
write (client_socket, msg, sizeof(struct Msg));
sqlite3_close(db);
return 0;
}
int change_password(int client_socket, struct Msg *msg)//修改密碼
{
sqlite3 *db;
int ret = sqlite3_open("chatroom.db", &db);
if(ret != SQLITE_OK)
{
printf("打開數據庫失敗\n");
return -1;
}
printf("打開數據庫成功\n");
char buf[100];
char *errmsg = NULL;
//改寫數據庫中的簽名
sprintf(buf, "update login set password = '%s' where name = '%s'", msg->password, msg->name);
ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("數據庫操作失敗:%s\n", errmsg);
msg->cmd = -1;
return -1;
}
else
{
printf("修改信息成功\n");
msg->cmd = 1009;
}
//反饋結果給客戶端
write (client_socket, msg, sizeof(struct Msg));
sqlite3_close(db);
return 0;
}
int send_file(int client_socket, struct Msg *msg)//處理文件
{
printf("%s 要給%s 發一條消息\n", msg->fromname, msg->toname);
// && (strcmp(tmp->data.name, msg->toname) == 0)
Node *tmp = head->next;
while(tmp != NULL)
{
// printf("11111111111111\n");
if(strncmp(tmp->data.name, msg->toname,strlen(msg->toname) - 1) == 0)
{
write(tmp->data.socket, msg, sizeof(struct Msg));
printf("套接字%d\n", tmp->data.socket);
// printf("11222222222221\n");
}
tmp = tmp->next;
}
}
void* handle_client(void *v)//處理客戶端消息控制檯
{
int client_socket = (int)v;
struct Msg msg;
while(1)
{
int ret = read(client_socket, &msg, 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 : //登錄
login(client_socket, &msg);
break;
case 3 : //羣聊
group_chat(client_socket, &msg);
break;
case 4 : //查看在線好友
Display(client_socket, &msg);
break;
case 5 :
private_chat(client_socket, &msg);
break;
case 6 :
Quit(client_socket, &msg);
break;
case 7 :
logout(client_socket, &msg);
break;
case 8 :
change_sign(client_socket, &msg);
break;
case 9 :
change_password(client_socket, &msg);
break;
case 10 :
send_file(client_socket, &msg);
break;
case 20:
signature(client_socket, &msg);
break;
}
}
close(client_socket);
}
int main()
{
//初始化套接字
int listen_socket = init_socket();
head = Create_List();
while(1)
{
//獲取與客戶端連接套接字
int client_socket = Accept(listen_socket);
pthread_t id;
pthread_create(&id, NULL, handle_client, (void *)client_socket);
pthread_detach(id);//線程分離
}
close(listen_socket);
return 0;
}
客戶端:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PORT 9999
struct Msg
{
int len;
int a[20];
char msg[1024];
char name[20];
char password[20];
char guys[100];
char toname[20];
char fromname[20];
char quitname[20];
char logoutname[20];
char sign[20];
int cmd;
};
char Myname[20];
char* signature(int socketfd)
{
struct Msg msg;
msg.cmd = 20;
strcpy(msg.name, Myname);
write(socketfd, &msg, sizeof(msg));
read(socketfd, &msg, sizeof(msg));
char *buf = (char *)malloc(20);
strcpy(buf, msg.sign);
return buf;
}
void interface1()
{
struct tm *ptr;
time_t lt;
lt =time(NULL);
ptr=gmtime(<);
// char str[100];
// strcpy(str, asctime(ptr));
// int i = 0;
// while(str[i] != '\n')
// {
// i++;
// }
// str[i] = '\0';
printf("\t\t\t****************************************\n");
printf("\t\t\t*");
printf(asctime(ptr));
printf("\t\t\t****************************************\n");
printf("\t\t\t* *\n");
printf("\t\t\t* *\n");
printf("\t\t\t* *\n");
printf("\t\t\t* *\n");
printf("\t\t\t* 1、註冊 *\n");
printf("\t\t\t* 2、登錄 *\n");
printf("\t\t\t* 3、退出聊天室 *\n");
printf("\t\t\t* *\n");
printf("\t\t\t* *\n");
printf("\t\t\t* *\n");
printf("\t\t\t* *\n");
printf("\t\t\t****************************************\n");
}
void interface2(char *buf)
{
struct tm *ptr;
time_t lt;
lt =time(NULL);
ptr=gmtime(<);
char str[100];
strcpy(str, asctime(ptr));
int i = 0;
while(str[i] != '\n')
{
i++;
}
str[i] = '\0';
printf("\t\t\t****************************************\n");
// printf("\t\t\t*");
// printf(asctime(ptr));
printf("\t\t\t*%s |=+=| :",str);
printf("%s\n", buf);
printf("\t\t\t****************************************\n");
printf("\t\t\t* *\n");
printf("\t\t\t* *\n");
// signature(socketfd);
printf("\t\t\t* *\n");
printf("\t\t\t* 1、羣聊 *\n");
printf("\t\t\t* 2、私聊 *\n");
printf("\t\t\t* 3、查看好友信息 *\n");
printf("\t\t\t* 4、退出登錄 *\n");
printf("\t\t\t* 5、查看聊天記錄 *\n");
printf("\t\t\t* 6、註銷用戶 *\n");
printf("\t\t\t* 7、修改個性簽名 *\n");
printf("\t\t\t* 8、修改密碼 *\n");
printf("\t\t\t* 9、文件傳輸 *\n");
printf("\t\t\t* *\n");
printf("\t\t\t* *\n");
printf("\t\t\t****************************************\n");
// printf("\t\t\t9、文件傳輸\n");
}
void Display(int socketfd)//查看在線好友
{
struct Msg msg;
"qwe";
msg.cmd = 4;
msg.len = 1;
// msg.msg =
// printf("1\n");
printf("\t\t\t在線好友名單:\n");
write(socketfd, &msg, sizeof(msg));
}
int read_file(struct Msg msg)//收文件
{
int fd2 = open("2.txt", O_WRONLY|O_CREAT, 0777);
if (fd2 == -1)
{
perror ("open fd2");
return -1;
}
int ret = 0;
char buf[1024] = {0};
strcpy(buf, msg.msg);
// printf("%s\n", msg.msg);
write (fd2, buf, strlen(buf));
}
void* readMsg(void *v)//線程分離獲取消息
{
int socketfd = (int)v;
struct Msg msg;
while(1)
{
read(socketfd, &msg, sizeof(msg));
// printf("%d\n", msg.cmd);
switch(msg.cmd)
{
case 3: // 羣聊
printf("\t\t\t收到一條消息:%s\n", msg.msg);
break;
case 5: // 私聊
printf("\t\t\t%s給你發了一條消息:%s\n", msg.fromname, msg.msg);
break;
case 4: // 查看在線人員
// printf("%d\n", msg.cmd);
// printf("在線好友名單:\n");
printf("\t\t\t%s\n", msg.guys);
break;
case 6:
printf("\t\t\t下線成功!\n");
return;
case 1007 :
printf("\t\t\t註銷成功!\n");
return;
case 1008 :
sleep(1);
printf("\t\t\t修改個性簽名成功!\n");
break;
case 1009 :
sleep(1);
printf("\t\t\t修改密碼成功!\n");
break;
case 10 :
read_file(msg);
break;
}
}
}
int chat_records_all(struct Msg msg, int flag)//存儲聊天信息
{
struct tm *ptr;
time_t lt;
lt =time(NULL);
ptr=gmtime(<);
char str[100];
strcpy(str, asctime(ptr));
// int len = strlen(str);
int i = 0;
while(str[i] != '\n')
{
i++;
}
str[i] = '\0';
int j = 0;
while(msg.toname[j] != '\n')
{
j++;
}
msg.toname[j] = '\0';
char pre[20];
if(flag == 1)
{
strcpy(pre, "all");
}
else if(flag == 0)
{
strcpy(pre, msg.toname);
}
// printf("%s\n", pre);
// printf(asctime(ptr));
// printf(ctime(<));
sqlite3 *db;
int ret = sqlite3_open("chatrecords.db", &db);
if(ret != SQLITE_OK)
{
printf("\t\t\t打開數據庫失敗\n");
return -1;
}
// printf("打開數據庫成功\n");
// 創建一張表records,用於存放羣聊信息
char *errmsg = NULL;
char *sql = "create table if not exists records(time TEXT, fromname TEXT, toname TEXT, msg TEXT,primary key(time))";
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("\t\t\t數據庫操作失敗:%s\n", errmsg);
return -1;
}
char buf[100];
// 將從收來的信息存放到數據庫中
sprintf(buf, "insert into records values('%s', '%s', '%s', '%s')", str, msg.fromname, pre, msg.msg);
ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("\t\t\t數據庫操作失敗:%s\n", errmsg);
return -1;
}
sqlite3_close(db);
}
void group_chat(int socketfd)//羣聊
{
struct Msg msg;
msg.cmd = 3;
printf("\t\t\t請輸入要發送的內容:");
// scanf("%s", msg.msg);
fgets(msg.msg, 1024, stdin);
strcpy(msg.fromname, Myname);
write (socketfd, &msg, sizeof(msg));
chat_records_all(msg, 1);
}
void private_chat(int socketfd)//私聊
{
struct Msg msg;
msg.cmd = 5;
printf("\t\t\t請輸入要發送對象的姓名:");
fgets(msg.toname, 20, stdin);
printf("\t\t\t請輸入要發送的內容:");
fgets(msg.msg, 1024, stdin);
strcpy(msg.fromname, Myname);
write (socketfd, &msg, sizeof(msg));
chat_records_all(msg, 0);
}
void reg(int socketfd)//註冊操作
{
struct Msg msg;
msg.cmd = 1;
char name[20];
char password[20];
char sign[20];
printf("\t\t\t請輸入您的姓名:");
scanf("%s", name);
printf("\t\t\t請輸入您的密碼:", password);
scanf("%s", password);
printf("\t\t\t請輸入您的個性簽名:");
scanf("%s", sign);
strcpy(msg.name, name);
strcpy(msg.password, password);
strcpy(msg.sign, sign);
write(socketfd, &msg, sizeof(msg));
read(socketfd, &msg, sizeof(msg));
if(msg.cmd == 1001)
{
printf("\t\t\t註冊成功\n");
}
else if(msg.cmd == -1)
{
printf("\t\t\t註冊失敗\n");
}
}
void Quit(int socketfd)//退出登錄
{
struct Msg msg;
msg.cmd = 6;
strcpy(msg.quitname, Myname);
write(socketfd, &msg, sizeof(msg));
}
int view_records()//記錄聊天記錄
{
sqlite3 *db;
int ret = sqlite3_open("chatrecords.db", &db);
if(ret != SQLITE_OK)
{
return -1;
}
char *errmsg = NULL;
char **resultp;
int nrow, ncolumn;
char *sql = "select * from records";
ret = sqlite3_get_table(db, sql, &resultp, &nrow, &ncolumn, &errmsg);
if(ret != SQLITE_OK)
{
printf("\t\t\t數據庫操作錯誤:%s\n", errmsg);
return -1;
}
int i;
// printf("nrow = %d, ncolume = %d\n", nrow, ncolumn);
for(i = 0; i < (nrow + 1) * ncolumn; i++)
{
if(i % ncolumn == 0)
{
printf("\n");
}
printf("%-28s", resultp[i]);
}
printf("\n");
sqlite3_close(db);
}
void logout(int socketfd)//註銷賬戶
{
struct Msg msg;
msg.cmd = 7;
strcpy(msg.logoutname, Myname);
write(socketfd, &msg, sizeof(msg));
}
void change_sign(socketfd)//修改個性簽名
{
struct Msg msg;
msg.cmd = 8;
char sign[20];
printf("\t\t\t請輸入您的新個性簽名:");
scanf("%s", sign);
strcpy(msg.name, Myname);
strcpy(msg.sign, sign);
write(socketfd, &msg, sizeof(msg));
}
void change_password(socketfd)//修改密碼
{
struct Msg msg;
msg.cmd = 9;
char password[20];
printf("\t\t\t請輸入您的新密碼:");
scanf("%s", password);
strcpy(msg.name, Myname);
strcpy(msg.password, password);
write(socketfd, &msg, sizeof(msg));
}
int send_file(int socketfd)// 發送文件
{
struct Msg msg;
msg.cmd = 10;
printf("\t\t\t當前目錄下文件\n");
char name[20];
char ptr[20];
// scanf("%s", ch);
// if(ch == "y")
// {
system("ls");
printf("請選擇你想發送的文件:");
scanf("%s", ptr);
int fd1 = open(ptr, O_RDWR);
if(fd1 == -1)
{
perror("open");
return -1;
}
char buf[1024] = {0};
int ret = read(fd1, buf, 1023);
buf[ret] = '\0';
// printf("%s\n", buf);
strcpy(msg.msg, buf);
printf("\t\t\t請輸入您要發送的對象:");
// fgets(msg.toname, 20, stdin);
scanf("%s", name);
strcpy(msg.toname, name);
strcpy(msg.fromname, Myname);
// printf("%s\n", msg.msg);
write(socketfd, &msg, sizeof(msg));
// }
// else
// {
// return;
// }
}
void oper(int socketfd, char *buf)//服務選擇2
{
while(1)
{
system("clear");
interface2(buf);
char ch[2];
printf("\t\t\t請輸入操作:");
scanf("%s",ch);
// fgets(ch, 2, stdin);
while(getchar()!= '\n');
// printf("ch[0]%c123 \n",ch[0]);
// printf("1\n");
if(strcmp(ch, "1") == 0)
{
group_chat(socketfd);
sleep(1);
printf("\t\t\t您可以按ENTER繼續您想要的操作!\n");
getchar();
getchar();
}
else if(strcmp(ch, "2") == 0)
{
private_chat(socketfd);
sleep(1);
printf("\t\t\t您可以按ENTER繼續您想要的操作!\n");
getchar();
getchar();
}
else if(strcmp(ch, "3") == 0)
{
printf("\t\t\t查找中........\n");
sleep(1);
Display(socketfd);
sleep(1);
printf("\t\t\t您可以按ENTER繼續您想要的操作!\n");
getchar();
getchar();
}
else if(strcmp(ch, "4") == 0)
{
printf("\t\t\t下線中........\n");
sleep(1);
Quit(socketfd);
sleep(1);
break;
}
else if(strcmp(ch, "5") == 0)
{
printf("\t\t\t查詢中............\n");
sleep(1);
view_records();
sleep(1);
printf("\t\t\t您可以按ENTER繼續您想要的操作!\n");
getchar();
getchar();
}
else if(strcmp(ch, "6") == 0)
{
printf("\t\t\t註銷中........\n");
sleep(1);
logout(socketfd);
sleep(1);
Quit(socketfd);
sleep(1);
break;
}
else if(strcmp(ch, "7") == 0)
{
change_sign(socketfd);
printf("\t\t\t修改中........\n");
sleep(2);
printf("\t\t\t您可以按ENTER繼續您想要的操作!\n");
getchar();
getchar();
}
else if(strcmp(ch, "8") == 0)
{
change_password(socketfd);
printf("\t\t\t修改中........\n");
sleep(1);
sleep(1);
printf("\t\t\t您可以按ENTER繼續您想要的操作!\n");
getchar();
getchar();
}
else if(strcmp(ch, "9") == 0)
{
send_file(socketfd);
}
}
}
void login(int socketfd)//登錄操作
{
struct Msg msg;
msg.cmd = 2;
// char Myname[20];
char password[20];
printf("\t\t\t請輸入您的姓名:");
scanf("%s", Myname);
// while(getchar()!= '\n');
printf("\t\t\t請輸入您的密碼:");
scanf("%s", password);
while(getchar()!= '\n');
strcpy(msg.name, Myname);
strcpy(msg.password, password);
write(socketfd, &msg, sizeof(msg));
read(socketfd, &msg, sizeof(msg));
// printf("%d\n", msg.cmd);
// printf("%s\n", signature(socketfd));
char buf[20];
strcpy(buf, signature(socketfd));
// printf("%s\n", buf);
if(msg.cmd == 1002)
{
printf("\t\t\t登錄成功\n");
pthread_t id;
pthread_create(&id, NULL, readMsg, (void *)socketfd);
pthread_detach(id);
oper(socketfd, buf);
}
else if(msg.cmd == -1)
{
printf("\t\t\t登錄失敗!\n");
}
else if(msg.cmd == -2)
{
printf("\t\t\t不存在該用戶!\n");
}
}
void ask_server(int socketfd)//服務選擇
{
char ch[2];
while (1)
{
system("clear");
interface1();
printf("\t\t\t請輸入您想進行的操作:");
scanf("%s", ch);
while(getchar() != '\n');
if(strcmp(ch, "1") == 0)
{
reg(socketfd);
}
else if(strcmp(ch, "2") == 0)
{
login(socketfd);
}
else if(strcmp(ch, "3") == 0)
{
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("\t\t\t成功連上服務器\n");
ask_server(socketfd);
close(socketfd);
return 0;
}