IT民工
分类: LINUX
2009-09-01 13:22:16
自己写的一个简单的猜数字游戏,server端用的多线程,用来练习socket 多线程的
留个记号!!
/*---------------------- code start ------------------------------*/
/*****************************************************
* 文件名: server.c
* 功能:服务器模型,CLIENT登陆后进入猜数字游戏
*
* 作者: liuwanxe -- <>
* 历史版本:
* 注意事项: 依赖文件 server.h
****************************************************/
#include "server.h"
#define STR -9 // 字符串标识
char cue_message[200];
int guess_times=0;
//pthread_mutex_t user_mutex; // 创建线程锁
/*****************************
* 初始化TCP服务器
* 返回值: 创建的套接字句柄
*****************************/
int tcp_server_init()
{
int serv_sockfd;
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
if ((serv_sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
{
printf("Creat socket failed !\n");
exit(1);
}
if ((bind(serv_sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr)))<0)
{
printf("bind port %d failed !\n",SERVER_PORT);
exit(1);
}
if ((listen(serv_sockfd,LISTEN_QUEUE))<0)
{
printf("server listen failed !\r\n ");
exit(1);
}
return serv_sockfd; // 返回套接字句柄
}
/******************************
* 将 字符串数转换成整数
*****************************/
int str_to_num(char *str)
{
int num=0,i=0;
char *tmp;
tmp = str;
while(tmp[i])
{
num += tmp[i] - '0';
if(tmp[i+1])
{
num *= 10;
}
else
{
return num;
}
i++;
}
return num;
}
/****************************
* 判断是不是字符串数字,
* 是则将字符串数转换成int 数
* 否则返回 STR 标识
****************************/
int check_str(char *buf)
{
int num;
char *tmp;
tmp=buf;
if(tmp[0]>='0' && tmp[0] <= '9')
{
num = str_to_num(tmp);
return num;
}
else
{
return STR;
}
}
/******************************
* 判断是否猜对
*****************************/
int slove_num(int num,int standard)
{
if(num < standard)
{
memset(cue_message,0,100);
memcpy(cue_message,"你输入的数太小\n",sizeof("你输入的数太小\n"));
// guess_times ++;
return ERR_NUM;
}
else if(num > standard)
{
memset(cue_message,0, 100);
memcpy(cue_message,"你输入的数太大\n",sizeof("你输入的数太大\n"));
// guess_times++;
return ERR_NUM;
}
else
{
memset(cue_message,0,100);
sprintf(cue_message,"恭喜!!!!猜对啦!!!\n你要猜的数是: %d \n继续游戏请输入\"y\"或\"Y\"\n",standard);
return SUCCESS;
}
}
/***************************
* 生成随机数
**************************/
int get_standard_num()
{
int num;
srand((int)time(0));
num = 1+(int)(100.0*rand()/(RAND_MAX+1.0));
return num;
}
/********************************
* 线程处理函数
*******************************/
void *tcp_thread(void *new_server_socket)
{
char recv_buf[NET_BUF_LEN];
char send_buf[NET_BUF_LEN];
int server_sockfd = (int)new_server_socket;
int result=DEFAULT;
int flag,standard,first=1,err;
/*
if((send(server_sockfd,"tcp server ok",sizeof("tcp server ok"),0))<0)
{
printf("send error \r\n");
exit(1);
}
*/
while (result != EXIT)
{
if (first == 1)
{
standard = get_standard_num();
//printf("要猜的数是: %d \n",standard);
memset(cue_message,0,100);
memcpy(cue_message,"欢迎进入猜数字游戏!\
\n请输入一个从 0 到 100 之间的数:\n",\
sizeof("欢迎进入猜数字游戏!\n\
请输入一个从 0 到 100 之间的数:\n"));
first = 0;
guess_times = 0;
}
if((send(server_sockfd,cue_message,sizeof(cue_message),0))<0)
{
printf("send error \r\n");
exit(1);
}
if ((recv(server_sockfd,recv_buf,NET_BUF_LEN,0))<0)
{
printf("recv error !\r\n");
exit(1);
}
printf("recv ok: %s \n",recv_buf);
if (strcmp(recv_buf,"quit")==0)
{
result = EXIT;
printf("你要猜的数是 : %d \n",standard);
}
else if ((strcmp(recv_buf,"y")==0) || (strcmp(recv_buf,"Y")==0))
{
first = 1;
result = DEFAULT;
}
else
{
result = DEFAULT;
}
flag = check_str(recv_buf);
if(flag != STR)
{
err=slove_num(flag,standard);
if(err == SUCCESS)
{
guess_times = 0;
// first = 1;
printf("你要猜的数是%d \n",standard);
}
if(err == ERR_NUM)
{
guess_times++;
printf("guess_times = %d \n",guess_times);
}
if(guess_times == 10)
{
memset(cue_message,0,200);
memcpy(cue_message,"对不起,你已经超出最大猜数次数! Game over !!\n,继续游戏请输入'y'或 'Y',退出请输入'quit' \n",150);
memset(recv_buf,0,50);
sprintf(recv_buf,"你要猜的数是: %d \n",standard);
strcat(cue_message,recv_buf);
}
}
#if 0
if ((recv(server_sockfd,recv_buf,NET_BUF_LEN,0))<0)
{
printf("recv error !\r\n");
exit(1);
}
printf("recv ok: %s \n",recv_buf);
if (strcmp(recv_buf,"ok")==0)
{
memset(recv_buf,0,NET_BUF_LEN);
if((send(server_sockfd,"ok",sizeof("ok"),0))<0)
{
printf("send error \r\n");
exit(1);
}
result = DEFAULT;
printf("send ok \n");
}
else if (strcmp(recv_buf,"quit")==0)
{
memset(recv_buf,0,NET_BUF_LEN);
if ((send (server_sockfd,"this tcp thread is close,bye bye!\n",\
sizeof("this tcp thread is close,bye bye!\n"),0))<0)
{
printf("send error !\n");
exit(1);
}
printf("close tcp server thread !\n");
result = EXIT;
}
else
{
memset(send_buf,0,NET_BUF_LEN);
sprintf(send_buf,"you have send \" %s \" to me,thank you !\n", recv_buf);
if ((send (server_sockfd,send_buf,NET_BUF_LEN,0))<0)
{
printf("send error !\n");
exit(1);
}
printf("send ok!\n");
memset(recv_buf,0,NET_BUF_LEN);
result = DEFAULT;
}
#endif
}
pthread_exit(NULL);
}
int main()
{
int sockfd,cli_sockfd;
struct sockaddr_in client_addr;
socklen_t length;
pthread_t thread_id;
sockfd = tcp_server_init();
while (1)
{
length = sizeof(client_addr);
printf("start accept \n");
if ((cli_sockfd = accept(sockfd,(struct sockaddr *)&client_addr,&length))<0)
{
printf("tcp server accept error! \n");
break;
}
if(pthread_create(&thread_id,NULL,tcp_thread,(void*)cli_sockfd)<0)
{
printf("tcp server create thread error:%s !\n",strerror(errno));
}
else
{
printf("create thread : thread_id -> %d ok !\n",thread_id);
}
}
close(sockfd);
pthread_exit(NULL);
return 0;
}
/*----------------------- end server.c ---------------------*/
/*--------------------- server.h -----------------*/
#ifndef _SERVER_H
#define _SERVER_H
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVER_PORT 1200 // 绑定端口
#define LISTEN_QUEUE 25 //监听队列的长度
#define DEFAULT 1 //默认值
#define EXIT -1 // 退出
#define NET_BUF_LEN 512 // 接收&发送 缓冲区长度
#define SUCCESS 1 // 猜对
#define ERR_NUM -2 // 猜错
#endif // _SERVER_H
/*----------------- end server.h -----------*/