108 lines
3.6 KiB
C
108 lines
3.6 KiB
C
|
// client.c
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <unistd.h>
|
||
|
#include <pthread.h>
|
||
|
#include <netinet/in.h>
|
||
|
#include "protocol.h"
|
||
|
|
||
|
#define SERVER_IP "127.0.0.1"
|
||
|
#define PORT 8888
|
||
|
|
||
|
int sockfd;
|
||
|
char username[MAX_NAME_LEN];
|
||
|
|
||
|
// 接收消息线程
|
||
|
void *recv_thread(void *arg) {
|
||
|
Message msg;
|
||
|
while (1) {
|
||
|
int n = recv(sockfd, &msg, sizeof(msg), 0);
|
||
|
if (n <= 0) break;
|
||
|
if (msg.type == MSG_PRIVATE_CHAT) {
|
||
|
printf("\n[私聊]%s: %s\n", msg.from, msg.data);
|
||
|
printf(">> ");
|
||
|
fflush(stdout);
|
||
|
}
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
void menu() {
|
||
|
printf("1. 注册\n2. 登录\n选择: ");
|
||
|
}
|
||
|
|
||
|
void chat_menu() {
|
||
|
printf("1. 添加好友\n2. 私聊\n3. 退出\n选择: ");
|
||
|
}
|
||
|
|
||
|
int main() {
|
||
|
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||
|
struct sockaddr_in servaddr = {0};
|
||
|
servaddr.sin_family = AF_INET;
|
||
|
servaddr.sin_port = htons(PORT);
|
||
|
inet_pton(AF_INET, SERVER_IP, &servaddr.sin_addr);
|
||
|
connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
|
||
|
|
||
|
int choice;
|
||
|
Message msg, reply;
|
||
|
while (1) {
|
||
|
menu();
|
||
|
scanf("%d", &choice);
|
||
|
getchar();
|
||
|
memset(&msg, 0, sizeof(msg));
|
||
|
if (choice == 1) {
|
||
|
msg.type = MSG_REGISTER;
|
||
|
printf("用户名: "); fgets(msg.from, MAX_NAME_LEN, stdin); msg.from[strcspn(msg.from, "\n")] = 0;
|
||
|
printf("密码: "); fgets(msg.data, MAX_MSG_LEN, stdin); msg.data[strcspn(msg.data, "\n")] = 0;
|
||
|
send(sockfd, &msg, sizeof(msg), 0);
|
||
|
recv(sockfd, &reply, sizeof(reply), 0);
|
||
|
if (reply.type == MSG_OK) printf("注册成功\n");
|
||
|
else printf("注册失败: %s\n", reply.data);
|
||
|
} else if (choice == 2) {
|
||
|
msg.type = MSG_LOGIN;
|
||
|
printf("用户名: "); fgets(msg.from, MAX_NAME_LEN, stdin); msg.from[strcspn(msg.from, "\n")] = 0;
|
||
|
printf("密码: "); fgets(msg.data, MAX_MSG_LEN, stdin); msg.data[strcspn(msg.data, "\n")] = 0;
|
||
|
send(sockfd, &msg, sizeof(msg), 0);
|
||
|
recv(sockfd, &reply, sizeof(reply), 0);
|
||
|
if (reply.type == MSG_OK) {
|
||
|
strcpy(username, msg.from);
|
||
|
printf("登录成功\n");
|
||
|
break;
|
||
|
} else {
|
||
|
printf("登录失败: %s\n", reply.data);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pthread_t tid;
|
||
|
pthread_create(&tid, NULL, recv_thread, NULL);
|
||
|
|
||
|
while (1) {
|
||
|
chat_menu();
|
||
|
scanf("%d", &choice);
|
||
|
getchar();
|
||
|
if (choice == 1) {
|
||
|
msg.type = MSG_ADD_FRIEND;
|
||
|
strcpy(msg.from, username);
|
||
|
printf("好友用户名: "); fgets(msg.to, MAX_NAME_LEN, stdin); msg.to[strcspn(msg.to, "\n")] = 0;
|
||
|
send(sockfd, &msg, sizeof(msg), 0);
|
||
|
recv(sockfd, &reply, sizeof(reply), 0);
|
||
|
if (reply.type == MSG_OK) printf("添加好友成功\n");
|
||
|
else printf("添加失败: %s\n", reply.data);
|
||
|
} else if (choice == 2) {
|
||
|
msg.type = MSG_PRIVATE_CHAT;
|
||
|
strcpy(msg.from, username);
|
||
|
printf("好友用户名: "); fgets(msg.to, MAX_NAME_LEN, stdin); msg.to[strcspn(msg.to, "\n")] = 0;
|
||
|
printf("消息内容: "); fgets(msg.data, MAX_MSG_LEN, stdin); msg.data[strcspn(msg.data, "\n")] = 0;
|
||
|
send(sockfd, &msg, sizeof(msg), 0);
|
||
|
recv(sockfd, &reply, sizeof(reply), 0);
|
||
|
if (reply.type == MSG_OK) printf("消息已发送\n");
|
||
|
else printf("发送失败: %s\n", reply.data);
|
||
|
} else if (choice == 3) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
close(sockfd);
|
||
|
return 0;
|
||
|
}
|