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模块 ...
随机推荐
- sqlite在c++中的使用方法
1.需要下载的文件 http://pan.baidu.com/s/1c06NpzM 2.执行文件shell的编译 3.在c++中如何使用 #include <stdio.h> # ...
- [转载]字符编码笔记:ASCII,Unicode和UTF-8
[转载] :http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html 1. ASCII码 在计算机内部,所有的信息最终都表 ...
- 协同办公平台Worktile体验分享(转)
自从组建团队以来,做的每一个项目.每一次活动,电脑里就会存放了N个不同名称的相同文档, 工作内容.资源文档非常零散,严重影响了工作效率. 之前用Dropbox共享文档,结果被墙了.用印象笔记,结果一个 ...
- JAVA笔记(一)super and this
http://zhangjunhd.blog.51cto.com/113473/20531 总结关键字this与super用法. author: ZJ 07-3-12 Blog: [url]http: ...
- Dragon Balls--hdu3635(并查集)
Dragon Balls Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 关于C#的一点小知识 以后自己用
项目过程中遇到C#代码的编写 上网查之后的结果 @html.ActionLink的几种参数格式 一 Html.ActionLink("linkText","actionN ...
- PHP设计模式之委托模式
委托模式: 通过分配或委托至其他对象,委托设计模式能够去除核心对象中的判决和复杂的功能性. class Bank{ protected $info; /* 设置基本信息 @param string $ ...
- Oracle EBS-SQL (BOM-19):主BOM与替代BOM互换.sql
替代BOM与主BOM互相转换 BOM: 1-01-27-211 子件:1-01-27-416 ID:2202 BOM替代项:替代0001 子件: 1-01-26-204 ID:2 ...
- MFC 遍历FTP服务器目录中文乱码问题
在编写FTP客户端的时候我用的是server u来做我的测试服务器,而server u 默认使用utf-8作为默认字符集,vs则使用unicode作为默认字符集,所以会产生乱码,将server u的默 ...
- js 获取浏览器内核
<script language="JavaScript" type="text/javascript"> var browser = { ...