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模块 ...
随机推荐
- 【Heritrix基础教程之4】开始一个爬虫抓取的全流程代码分析
在创建一个job后,就要开始job的运行,运行的全流程如下: 1.在界面上启动job 2.index.jsp 查看上述页面对应的源代码 <a href='"+request.getCo ...
- .Net Service开发(一)
一, 新增一个服务项目
- listview滚动到底部
方法一: // msgListView是ListView控件 // adapter是ListView绑定的Adapter,如果不方便直接使用,也可以通过ListView的getAdapter()方法获 ...
- JavaScript 字符串常用操作纪要
JavaScript 字符串用于存储和处理文本.因此在编写 JS 代码之时她总如影随形,在你处理用户的输入数据的时候,在读取或设置 DOM 对象的属性时,在操作 Cookie 时,在转换各种不同 Da ...
- [汇编语言]-第八章 div指令,伪指令dd,dup
1- div除法指令 (1) 除数: 有8位和16位两种,在一个寄存器或内存单元中. (2) 被除数: 默认放在AX和DX或AX中 除数为8位, 被除数为16位, 默认在AX中存放. 除数为16位, ...
- Nginx 变量漫谈(六)
Nginx 内建变量用在“子请求”的上下文中时,其行为也会变得有些微妙. 前面在 (三) 中我们已经知道,许多内建变量都不是简单的“存放值的容器”,它们一般会通过注册“存取处理程序”来表现得与众不同, ...
- C# Chart 折线图 多条数据展示
private void btn_Click(object sender, EventArgs e) { DBHelper db = new DBHelper(); DataSet ds = db.G ...
- 切图教程,PS和AI切图方法分享
- poj 1328 Radar Installation_贪心
翻出一年多前的代码看,发现以前的代码风格很糟糕 题意:给你n个点 m为圆的半径,问需要多少个圆能把全部点圈到 #include <iostream> #include <algori ...
- Linux学习笔记6-Linux根目录下各个目录的作用
/bin:存放最常用命令: /boot:启动Linux的核心文件: /dev:设备文件: /etc:存放各种配置文件: /home:用户主目录: /lib:系统最基本的动态链接共享库: /mnt:一 ...