jchat:linux聊天程序3:服务器
makefile:
jchat_server: main.o process.o sql.o gcc -o jchat_server main.o process.o sql.o -L/usr/lib/mysql -lmysqlclient rm -f *.o *.gch *~ main.o: main.c process.h sql.h gcc -c main.c process.h sql.h -I/usr/include/mysql process.o: process.h process.h gcc -c process.c process.h -I/usr/include/mysql sql.o: sql.c sql.h gcc -c sql.c sql.h -I/usr/include/mysql clean: rm -f *.o *.gch *~ jchat_server
main.c:主函数
/*server/main.c*/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <netinet/in.h> #include "process.h" #include "sql.h" #define MAXLINE 4096 #define LISTENQ 1024 #define PORT 12345 int listenfd; pid_t pid_online_time, pid_conn; /* * init server create socket */ void server_init() { listenfd = socket(AF_INET, SOCK_STREAM, ); struct sockaddr_in servaddr; memset(&servaddr, , sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(PORT); bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); listen(listenfd, LISTENQ); } int main(int argc, char *argv[]) { server_init(); pid_online_time = fork(); ) { refresh_online_time(); } ) { struct sockaddr_in cliaddr; int clilen = sizeof(cliaddr); int connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen); ) { close(listenfd); process(connfd); } else { pid_t pid = getpid(); //printf("fork process pid = %d\n", pid); } close(connfd); } exit(); }
process.c:一个子进程用于处理一个客户端发来的所有请求
/*server/process.c*/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <netinet/in.h> #include <my_global.h> #include <my_sys.h> #include <mysql.h> #include "process.h" #include "sql.h" #define MAXLINE 4096 char sendbuff[MAXLINE], recvbuff[MAXLINE]; int recv_len; /* * all users' online time - 1 every second */ void refresh_online_time() { MYSQL *conn = sql_init(); ) { mysql_query(conn, "update jchat.user set online_time=online_time-1 \ ;"); //printf("refresh online time -1\n"); sleep(); } } /* * regist new user * fail when user exists already */ void regist(int sockfd) { MYSQL *conn = sql_init(); int i, j, k, l; i = ;j = ; while (recvbuff[j] != ':') ++j; k = j + ; ], passwd[]; for (l=i; l<j; ++l) { user[l-i] = recvbuff[l]; } user[j-i] = '\0'; for (l=k; l<recv_len; ++l) { passwd[l-k] = recvbuff[l]; } user[recv_len-k] = '\0'; ]; sprintf(query, \ "select * from jchat.user where user='%s';", \ user); mysql_query(conn, query); MYSQL_RES *res = mysql_use_result(conn); MYSQL_ROW row = mysql_fetch_row(res); if (row != NULL) { // exist user sendbuff[] = ] = '\0'; } else { sendbuff[] = ] = '\0'; sprintf(query, \ "insert into jchat.user values('%s','%s',0);", \ user, passwd); mysql_query(conn, query); } mysql_free_result(res); write(sockfd, sendbuff, strlen(sendbuff)); //printf("sendbuff> '%s'\n", sendbuff); sql_exit(conn); printf("regist user=%s passwd=%s\n", user, passwd); } /* * login a user * fail if user and password not match */ void login(int sockfd) { MYSQL *conn = sql_init(); int i, j, k, l; i = ;j = ; while (recvbuff[j] != ':') ++j; k = j + ; ], passwd[]; for (l=i; l<j; ++l) { user[l-i] = recvbuff[l]; } user[j-i] = '\0'; for (l=k; l<recv_len; ++l) { passwd[l-k] = recvbuff[l]; } user[recv_len-k] = '\0'; ]; sprintf(query, \ "select * from jchat.user where user='%s' and passwd='%s';", \ user, passwd); mysql_query(conn, query); MYSQL_RES *res = mysql_use_result(conn); MYSQL_ROW row = mysql_fetch_row(res); if (row != NULL) { // user and passwd correct sendbuff[] = ] = '\0'; sprintf(query, \ "update jchat.user set online_time=7 \ where user='%s';", user); mysql_query(conn, query); } else { sendbuff[] = ] = '\0'; } mysql_free_result(res); write(sockfd, sendbuff, strlen(sendbuff)); //printf("sendbuff> '%s'\n", sendbuff); sql_exit(conn); printf("login user=%s passwd=%s\n", user, passwd); } /* * get user online notice and update online time to 12 */ void user_at() { MYSQL *conn = sql_init(); int i; ]; ; i<recv_len; ++i) { user[i-] = recvbuff[i]; } user[recv_len-] = '\0'; ]; sprintf(query, \ "update jchat.user set online_time=12 where user='%s';", \ user); mysql_query(conn, query); sql_exit(conn); //printf("%s is online\n", user); } /* * return a user's unread message * and delete the message in mysql */ void get_mesg(int sockfd) { MYSQL *conn = sql_init(); int i; ]; ; i<recv_len; ++i) { user[i-] = recvbuff[i]; } user[recv_len-] = '\0'; ]; sprintf(query, \ "select * from jchat.user where \ user='%s';", user); mysql_query(conn, query); MYSQL_RES *res = mysql_use_result(conn); MYSQL_ROW row = mysql_fetch_row(res); if (row != NULL) { // user exist mysql_free_result(res); sprintf(query, \ "select * from jchat.mesg where recvuser='%s';", \ user); mysql_query(conn, query); ], recvuser[], text[]; res = mysql_use_result(conn); sendbuff[] = '\0'; ; while ((row = mysql_fetch_row(res)) != NULL) { hasMesg = ; int row_num = mysql_num_fields(res); strcpy(senduser, row[]); strcpy(recvuser, row[]); strcpy(text, row[]); strcat(sendbuff, senduser); strcat(sendbuff, ":" ); strcat(sendbuff, text ); strcat(sendbuff, ";" ); } if (!hasMesg) { strcpy(sendbuff, ";"); } mysql_free_result(res); sprintf(query, \ "delete from jchat.mesg where recvuser='%s';", \ user); mysql_query(conn, query); write(sockfd, sendbuff, strlen(sendbuff)); //printf("get_mesg sendbuff> '%s'\n", sendbuff); } sql_exit(conn); //printf("%s get message from server\n", user); } /* * one user send message to another user * store to mysql */ void send_mesg() { MYSQL *conn = sql_init(); int i, j, k, x; i = ;j = ; while (recvbuff[j] != ':') ++j; ++j; k = j + ; while (recvbuff[k] != ':') ++k; ++k; //printf("i=%d, j=%d, k=%d\n",i,j,k); ], recvuser[], text[]; ; x<j--i; ++x) { senduser[x] = recvbuff[x+i]; } senduser[j--i] = '\0'; ; x<k--j; ++x) { recvuser[x] = recvbuff[x+j]; } recvuser[k--j] = '\0'; ; x<recv_len-k; ++x) { text[x] = recvbuff[x+k]; } text[recv_len-k] = '\0'; //printf("senduser = '%s'\nrecvuser = '%s'\n", senduser, recvuser); ; ]; sprintf(query, \ "select * from jchat.user where user='%s';", \ senduser); mysql_query(conn, query); MYSQL_RES *res = mysql_use_result(conn); MYSQL_ROW row = mysql_fetch_row(res); if (row == NULL) { // send user not exist user_exist = ; } mysql_free_result(res); sprintf(query, \ "select * from jchat.user where user='%s';", \ recvuser); mysql_query(conn, query); res = mysql_use_result(conn); row = mysql_fetch_row(res); if (row == NULL) { // recv user not exist user_exist = ; } mysql_free_result(res); if (user_exist) { sprintf(query, \ "insert into jchat.mesg values('%s','%s','%s');", \ senduser, recvuser, text); mysql_query(conn, query); } sql_exit(conn); printf("%s send message to %s\n", senduser, recvuser); } /* * return current online users */ void online_user(int sockfd) { MYSQL *conn = sql_init(); mysql_query(conn, "select user from jchat.user where online_time>0;"); sendbuff[] = '\0'; MYSQL_RES *res = mysql_use_result(conn); MYSQL_ROW row; ; while ((row = mysql_fetch_row(res)) != NULL) { hasOnline = ; strcat(sendbuff, row[]); strcat(sendbuff, ";" ); } if (!hasOnline) { strcpy(sendbuff, ";"); } mysql_free_result(res); write(sockfd, sendbuff, strlen(sendbuff)); //printf("online_user sendbuff> '%s'\n", sendbuff); sql_exit(conn); } /* * user quit * update online time to 0 */ void quit() { MYSQL *conn = sql_init(); int i; ]; ; i<recv_len; ++i) { user[i-] = recvbuff[i]; } user[recv_len-] = '\0'; ]; sprintf(query, \ "update jchat.user set online_time=0 where user='%s';", \ user); mysql_query(conn, query); printf("%s quit\n", user); sql_exit(conn); exit(); // exit this process } void process(int sockfd) { ) { recvbuff[recv_len] = '\0'; //printf("process recvbuff> '%s'\n", recvbuff); ]) { case 'r': // regist regist(sockfd); break; case 'l': // login login(sockfd); break; case 'a': // online notice user_at(); break; case 'g': // get message get_mesg(sockfd); break; case 's': // send message send_mesg(); break; case 'o': // online user check online_user(sockfd); break; case 'q': // quit quit(); break; } } }
process.h:
/*server/process.h*/ #ifndef PROCESS_H #define PROCESS_H #include <my_global.h> #include <my_sys.h> #include <mysql.h> /* * refresh online user's online time every minute * seemed as offline if online time decrease to 0 */ void refresh_online_time(); /* * process different command from client */ void process(int sockfd); #endif // PROCESS_H
sql.c:新建mysql的连接
/*server/sql.h*/ #include <my_global.h> #include <my_sys.h> #include <mysql.h> #include "sql.h" static char *host_name = "localhost"; static char *user_name = "your mysql user"; // 这里要更换为自己mysql用户的用户名与密码 static char *passwd = "your mysql password"; ; static char *socket_name = NULL; static char *db_name = "jchat"; ; MYSQL *sql_init() { MYSQL *conn; MY_INIT("jchat_server"); ,NULL,NULL)) { fprintf(stderr, "mysql_library_init() failed\n"); return NULL; } conn = mysql_init(NULL); if (conn == NULL) { fprintf(stderr, "mysql_init() failed\n"); return NULL; } if (mysql_real_connect(conn,host_name,user_name,passwd, db_name,port_num,socket_name,flags) == NULL) { fprintf(stderr, "mysql_real_connect() failed\n"); mysql_close(conn); return NULL; } return conn; } void sql_exit(MYSQL *conn) { mysql_close(conn); mysql_library_end(); }
sql.h:
/*server/sql.h*/ #ifndef SQL_H #define SQL_H #include <my_global.h> #include <my_sys.h> #include <mysql.h> /* * link to mysql * return 1 if succeed, 0 if fail */ MYSQL *sql_init(); void sql_exit(MYSQL *conn); #endif // SQL_H
jchat:linux聊天程序3:服务器的更多相关文章
- jchat:linux聊天程序1:简介
做一个linux的聊天软件,虽然没什么创意,但是它可以用来锻炼和测试我对网络编程的掌握程度,也借此机会做一些有意思的程序. 这里做的是linux下一个命令行的客户端与服务器的聊天程序,没写界面,因为对 ...
- jchat:linux聊天程序4:客户端
makefile: jchat: main.o login.o regist.o tcp.o gcc -w main.o login.o regist.o tcp.o -o jchat rm -f * ...
- jchat:linux聊天程序2:MySQL
该软件使用的数据库为MySQL,因为它免费.开源,在linux下几乎就是最好的选择. 首先要在mysql中root用户新建数据库并赋权给本用户: create database jchat; gran ...
- Socket编程实践(3) 多连接服务器实现与简单P2P聊天程序例程
SO_REUSEADDR选项 在上一篇文章的最后我们贴出了一个简单的C/S通信的例程.在该例程序中,使用"Ctrl+c"结束通信后,服务器是无法立即重启的,如果尝试重启服务器,将被 ...
- Node.js + Web Socket 打造即时聊天程序嗨聊
前端一直是一块充满惊喜的土地,不仅是那些富有创造性的页面,还有那些惊赞的效果及不断推出的新技术.像node.js这样的后端开拓者直接将前端人员的能力扩大到了后端.瞬间就有了一统天下的感觉,来往穿梭于前 ...
- hello/hi的简单的网络聊天程序
hello/hi的简单的网络聊天程序 0 Linux Socket API Berkeley套接字接口,一个应用程序接口(API),使用一个Internet套接字的概念,使主机间或者一台计算机上的进程 ...
- 以您熟悉的编程语言为例完成一个hello/hi的简单的网络聊天程序
Socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信,应用程序通常通过"套接字"向网络发出 ...
- java swing+socket实现多人聊天程序
swing+socket实现多人聊天程序 1.准备工作 先看效果: 客户端项目结构图: 服务端项目结构图: 2.运行原理 服务端 先开一个线程serverListerner,线程中开启一个Server ...
- Socket聊天程序——Common
写在前面: 上一篇记录了Socket聊天程序的客户端设计,为了记录的完整性,这里还是将Socket聊天的最后一个模块--Common模块记录一下.Common的设计如下: 功能说明: Common模块 ...
随机推荐
- [Effective Modern C++] Item 6. Use the explicitly typed initializer idiom when auto deduces undesired types - 当推断意外类型时使用显式的类型初始化语句
条款6 当推断意外类型时使用显式的类型初始化语句 基础知识 当使用std::vector<bool>的时候,类型推断会出现问题: std::vector<bool> featu ...
- oracle 集合定义
集合:是具有相同定义的元素的聚合.Oracle有两种类型的集合: 可变长数组(VARRAY):可以有任意数量的元素,但必须预先定义限制值. 嵌套表:视为表中之表,可以有任意数量的元素,不需要预先定义限 ...
- 初学swift笔记 结构体(八)
import Foundation /* 和类很相似 结构体 -> 封装 属性.方法 结构体是值类型 */ //定义一个LSQ类型的结构体 关键字struct struct LSQ { var ...
- 组合数(DFS)
组合数 点我 描述 找出从自然数1.2.... .n(0<n<10)中任取r(0<r<=n)个数的所有组合. 输入 输入n.r. 输出 按特定顺序输出所有组合.特定顺序 ...
- 今天在研究jquery用ajax提交form表单中得数据时,学习到了一种新的提交方式
今天在研究jquery用ajax提交form表单中得数据时,学习到了一种新的提交方式 jquery中的serialize() 方法 该方法通过序列化表单值,创建 URL 编码文本字符串 序列化的值可在 ...
- MYSQL 数据类型的 3 个注意
注意 1. bit(Length) 这种数据类型中,最大长度只可以是64.就是说 bit(2) 对 bit(64) 对 bit(65) 错 bit(100) 错 注 ...
- AIX安装SSH
AIX 7.1 进入 https://www14.software.ibm.com/webapp/iwm/web/preLogin.do?source=aixbp 先下载需要的openssl,op ...
- http协言和web本质
http协议和web本质 作为一个开发者,尤其是web开发人员,我想你有必要去了解这一系列的处理流程,在这期间,浏览器和服务器到底是如何打交道的?服务器又是如何处理的?浏览器又是如何将网页显示给用户的 ...
- Silence.js高效开发移动Web前端类库
基于Zepto的轻量级移动Web前端JavaScript类库. 编写这个类库原因及目的: 采用MVC设计模式,使代码工程化结构化. 使用RouterJS,提升前端交互性能,延长页面使用时间,并通过Aj ...
- Curly braces in Python in 2012? - Stack Overflow
Curly braces in Python in 2012? - Stack Overflow Curly braces in Python in 2012? [closed]