工程实践实训日报九
项目名称 【苏嵌实训-嵌入式 linux C 第 9天】
今日进度以及任务 学习聊天室之私聊和群聊的实现。
本日任务完成情况
在昨天的基础上继续完善功能,练习了C/S模式下聊天室的实现。
本日开发中出现的问题汇总 写代码的速度还是跟不上,课后看回放才完成了聊天室的私聊群聊功能。
本日未解决问题 无
本日开发收获 学会了利用多线程创建聊天室,以及私聊与群聊功能的分别实现。
其他 无
//客户端
**//client**
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/unistd.h>
#include <sys/un.h>
#include <pthread.h>
#include <string.h>
#define PORT 33333
struct message {
int op;
char toname[20];
char msg[1024];
};
void *recv_message(void *arg) {
int ret;
int cfd = *((int *) arg);
//char buffer[1024];
struct message *msg = (struct message *) malloc(sizeof(struct message));
while (1) {
memset(msg, 0, sizeof(struct message));
if ((ret = recv(cfd, msg, sizeof(struct message), 0)) < 0) {
printf("recv error!\n");
exit(1);
}
if (ret == 0) {
printf("%d is closed!\n", cfd);
pthread_exit(NULL);
}
// printf("recv = %s\n", buffer);
switch (msg->op) {
case 1: {
printf("reg success!\n");
break;
}
case 2: {
printf("recv: %s\n", msg->msg);
break;
}
case 3: {
printf("all recv: %s\n", msg->msg);
break;
}
}
usleep(3);
}
}
int main() {
int sockfd;
struct sockaddr_in s_addr;
// char buffer[1024];
char cmd[20];
char name[20];
char toname[20];
char msge[1024];
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket error!\n");
exit(1);
}
printf("client socket success!\n");
bzero(&s_addr, sizeof(struct sockaddr_in));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
s_addr.sin_addr.s_addr = inet_addr("192.168.17.128");
if (connect(sockfd, (struct sockaddr *) (&s_addr), sizeof(struct sockaddr_in)) < 0) {
perror("connect error!\n");
exit(1);
}
printf("connect success!\n");
pthread_t id;
if (pthread_create(&id, NULL, recv_message, (void *) (&sockfd)) != 0) {
perror("pthread_create error!\n");
exit(1);
}
struct message *msg = (struct message *) malloc(sizeof(struct message));
while (1) {
printf("Input cmd(reg send all):\n");
scanf("%s", cmd);
if (strcmp(cmd, "reg") == 0) {
printf("Input reg name:\n");
scanf("%s", name);
msg->op = 1;
strcpy(msg->msg, name);
if (send(sockfd, msg, sizeof(struct message), 0) < 0) {
perror("send error!\n");
exit(1);
}
}
if (strcmp(cmd, "send") == 0) {
printf("Input send to name:\n");
scanf("%s", toname);
printf("Input send message:\n");
scanf("%s", msge);
msg->op = 2;
strcpy(msg->toname, toname);
strcpy(msg->msg, msge);
send(sockfd, msg, sizeof(struct message), 0);
}
if (strcmp(cmd, "all") == 0) {
printf("Input send to all message:\n");
scanf("%s", msge);
msg->op = 3;
strcpy(msg->msg, msge);
send(sockfd, msg, sizeof(struct message), 0);
}
}
shutdown(sockfd, SHUT_RDWR);
return 0;
}
//服务器
**//server**
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/unistd.h>
#include <sys/un.h>
#include <pthread.h>
#include <string.h>
struct message {
int op;
char toname[20];
char msg[1024];
};
struct online {
int cfd;
char name[20];
struct online *next;
};
struct online *head = NULL;
void insert_user(struct online *new) {
if (head == NULL) {
new->next = NULL;
head = new;
} else {
new->next = head->next;
head->next = new;
}
}
int find_cfd(char *toname) {
if (head == NULL) {
return -1;
}
struct online *temp = head;
while (temp != NULL) {
if (strcmp(temp->name, toname) == 0) {
return temp->cfd;
}
temp = temp->next;
}
return -1;
}
void *recv_message(void *arg) {
int ret;
int cfd = *((int *) arg);
//char buffer[1024];
struct message *msg = (struct message *) malloc(sizeof(struct message));
struct online *new;
while (1) {
memset(msg, 0, sizeof(struct message));
if ((ret = recv(cfd, msg, sizeof(struct message), 0)) < 0) {
printf("recv error!\n");
exit(1);
}
if (ret == 0) {
printf("%d is closed!\n", cfd);
pthread_exit(NULL);
}
//printf("recv = %s\n", buffer);
switch (msg->op) {
case 1: {
//注册
new = (struct online *) malloc(sizeof(struct online));
new->cfd = cfd;
strcpy(new->name, msg->msg);
insert_user(new);
msg->op = 1;
send(cfd, msg, sizeof(struct message), 0);
break;
}
case 2: {
//私聊
int to_cfd = find_cfd(msg->toname);
if (to_cfd != -1) {
msg->op = 2;
send(to_cfd, msg, sizeof(struct message), 0);
}
break;
}
case 3: {
//群聊
struct online *temp = head;
int to_cfd;
while (temp != NULL) {
to_cfd = temp->cfd;
msg->op = 3;
send(to_cfd, msg, sizeof(struct message), 0);
temp = temp->next;
}
break;
}
}
usleep(3);
}
}
void *send_message(void *arg) {
int ret;
int cfd = *((int *) arg);
while (1) {
if ((ret = send(cfd, "hello world", 12, 0)) < 0) {
printf("send error!\n");
exit(1);
}
if (ret == 0) {
printf("%d is closed!\n", cfd);
pthread_exit(NULL);
}
sleep(3);
}
}
#define PORT 33333
int main() {
int sockfd;
int cfd;
int c_len;
struct sockaddr_in addr;
struct sockaddr_in c_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
perror("sock create error!\n");
exit(1);
}
printf("socket success!\n");
int opt = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
bzero(&addr, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr("192.168.17.128");
if (bind(sockfd, (struct sockaddr *) (&addr), sizeof(struct sockaddr_in)) < 0) {
perror("bind error!\n");
exit(1);
}
printf("bind success!\n");
if (listen(sockfd, 3) < 0) {
perror("listen error!\n");
exit(1);
}
printf("listen success!\n");
while (1) {
bzero(&c_addr, sizeof(struct sockaddr_in));
c_len = sizeof(struct sockaddr_in);
printf("accepting........\n");
cfd = accept(sockfd, (struct sockaddr *) (&c_addr), &c_len);
if (cfd < 0) {
perror("accept error!\n");
exit(1);
}
printf("accept success!\n");
printf("port = %d ip = %s \n", ntohs(c_addr.sin_port), inet_ntoa(c_addr.sin_addr));
// write(cfd,"hello",5);
// send(cfd, "hello", 5);
pthread_t id;
if (pthread_create(&id, NULL, recv_message, (void *) (&cfd)) != 0) {
printf("pthread_create error!\n");
exit(1);
}
/*if(pthread_create(&id, NULL, send_message, (void *)(&cfd)) != 0)
{
printf("pthread_create error!\n");
exit(1);
}*/
usleep(3);
}
//usleep(2);
//shutdown(cfd, SHUT_RDWR);
return 0;
}