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模块 ...
随机推荐
- T - 阿牛的EOF牛肉串(第二季水)
Description 今年的ACM暑期集训队一共有18人,分为6支队伍.其中有一个叫做EOF的队伍,由04级的阿牛.XC以及05级的COY组成.在共同的集训生活中,大家建立了深厚的 ...
- delete、update忘加where条件误操作恢复过程演示
update.delete没有带where条件,误操作,如何恢复呢? 我现在有一张学生表,我要把小于60更新成不及格. mysql> select * from student; +----+- ...
- MySql小知识点
1.查看MySql是什么编码 show create table tablename;
- SlimDX的DirectSound模块
网上SlimDX的资源很少,搜到了http://www.xukailun.me/article/238/这篇关于<SlimDX的DirectSound模块应用实战>的文章,备份下来以备不时 ...
- 函数 - PHP手册笔记
用户自定义函数 函数无需在调用前被定义,除非是有条件定义的. PHP中的所有函数和类都具有全局作用域.PHP不支持函数重载,也不可能取消定义或者重定义已声明的函数. 特意试了下,我的电脑上的PHP递归 ...
- Python之路第十一天,高级(3)-Python操作 Memcached、Redis
Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...
- Django学习(二) Django框架简单搭建
为了快速学习Python进行Web的开发,所以我不准备从Python的基础学起,直接从Django框架入手,边学框架边学Python的基础知识. 下面就开始Django的快速开发之旅吧. 关于Djan ...
- codeforces 519C.. A and B and Team Training
C. A and B and Team Training time limit per test 1 second memory limit per test 256 megabytes input ...
- win7 PHP7.0的PDO扩展
一个非常棘手的问题,win7(64位)环境,编译安装的mysql,php无法使用pdo扩展. 而我的centos中yum安装的php,pdo是好用的. 百度了一大堆,都无法解决. 基本上百度到的都是要 ...
- ActionResult 之HttpGet HttpPost
GET一般用于获取和查询数据. 当浏览器发送HTTP GET 请求的时候,会找到使用HttpGet限定的对应Action. POST 一般用于更新数据. 当Action上面没有限定的时候,浏览器发送任 ...