Chinaunix首页 | 论坛 | 博客
  • 博客访问: 489097
  • 博文数量: 130
  • 博客积分: 2111
  • 博客等级: 大尉
  • 技术积分: 1373
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-28 09:55
个人简介

IT民工

文章分类

全部博文(130)

文章存档

2021年(1)

2019年(1)

2017年(3)

2014年(1)

2013年(3)

2012年(2)

2011年(3)

2010年(2)

2009年(114)

分类: LINUX

2009-09-01 13:22:16

linux多线程+TCP服务器
2008-07-17 13:06:33

自己写的一个简单的猜数字游戏,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 -----------*/

阅读(1299) | 评论(0) | 转发(0) |
0

上一篇:linux多线程编程

下一篇:UDA1341播、录音[zt]

给主人留下些什么吧!~~