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模块 ...
随机推荐
- 班上有学生若干名,已知每名学生的成绩(整数),求班上所有学生的平均成绩,保留到小数点后两位。同时输出该平均成绩整数部分四舍五入后的数值。 第一行有一个整数n(1<= n <= 100),表示学生的人数。其后n行每行有1个整数,表示每个学生的成绩,取值在int范围内。
#include<iostream> #include<iomanip> using namespace std ; int main() { int n; while(cin ...
- Apache的httpd命令详解
Apache的httpd命令详解 来源:全栈开发者 发布时间:2012-01-03 阅读次数:10965 4 httpd.exe为Apache HTTP服务器程序.直接执行程序可启动服务器的服务. ...
- JQuery动态表格
功能实现:点击添加按钮,表格增加一行并给其name属性赋予的值,方便获取 点击删除,自动删除这一行 JQuery中定义一个count变量 var count = 1; function add() { ...
- PHP解决网站高流量高并发问题
首先,确认服务器硬件是否足够支持当前的流量. 普通的P4服务器一般最多能支持每天10万独立IP,如果访问量比这个还要大, 那么必须首先配置一台更高性能的专用服务器才能解决问题 ,否则怎么优化都不可能彻 ...
- coco2d-x中的坐标系问题
(1)OpenGL坐标系 Cocos2D-x以OpenGL和OpenGL ES为基础,所以自然支持OpenGL坐标系.该坐标系原点在屏幕左下角,x轴向右,y轴向上. (2)屏幕坐标系 屏幕坐标系使用的 ...
- SQL Server 内存压力解决方案
外部压力: 表现形式: 1.total server memory ↓ 2.avilable Mbyte 平衡 3.working set ↓ 如果说SQ ...
- nginx上传模块—nginx upload module-
一. nginx upload module原理 官方文档: http://www.grid.net.ru/nginx/upload.en.html Nginx upload module通过ngin ...
- 创建以 API 为中心的 Web 应用
http://www.oschina.net/translate/creating-an-api-centric-web-application?from=20130818 正计划着要开始搞一个新的网 ...
- Delphi利用Webbrowser登陆QQ群文档
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- 如何获取版本的 Internet 信息服务器 (IIS)
不同的操作系统对应不同IIS http://support.microsoft.com/kb/224609/zh-cn