日期:2014-05-16  浏览次数:20787 次

linux socket编程问题,下面是我做的一个简单的模拟银行排队叫号系统。
程序运行:开启多个终端,一个服务器,其余的是客户端(包括一个取号机和多个柜台叫号机)
问题:我把服务器和多个客户端程序可以正常运行,但当我按 ctr+c 键杀掉一个客户端后,服务器端的程序也会死掉,

请问怎样才能使 杀死客户端程序 而不使服务器端程序死掉? 要怎样修改程序,请高手指教。

下面是我的源程序:

服务器 server.c



#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <netdb.h>
#include <pthread.h>

/* 定义端口号,须大于1024 */
#define PORT 8888

//#define BUF_SIZE 1024

/* 信息宏 */
#define GEN_GOTAL 1 /* 普通业务总人数 */ 
#define GEN_CUR 2 /* 普通业务当前服务的号码 */
#define VIP_TOTAL 3 /* vip业务总人数 */
#define VIP_CUR 4 /* vip业务当前服务的号码 */


#define FROM_GET_NUM 5 /* 为取号机创建线程 */
#define FROM_CALL_NUM 6 /* 为叫号机创建线程 */

/* 存储服务人数信息结构定义 */
typedef struct
{
int gen_total_num; /* 普通业务总人数 */
  int gen_cur_num; /* 普通业务当前服务的号码 */

int vip_total_num; /* vip业务总人数 */
int vip_cur_num; /* vip业务当前服务的号码 */
}info_bank;

info_bank info_people;



/* 线程执行函数负责读写 */
void *server_client( void *arg );
/* 初始化服务信息 */
void init_info(info_bank *info_people);

void save_info_getnum(info_bank *info_people, int operation); /*保存取号机发来的信息*/
void save_info_call(info_bank *info_people, int operation); /*保存叫号机发来的信息*/


int main(int argc, char *argv[])
{
  socklen_t clt_addr_len;
int listen_fd;
int com_fd;
int ret;
int i;
static char recv_buf;
int len;

pthread_t tid;

struct sockaddr_in clt_addr;
struct sockaddr_in srv_addr;

init_info(&info_people);

/* 创建套接字用于服务器的监听 */
listen_fd = socket(PF_INET, SOCK_STREAM, 0);
if (listen_fd < 0)
{
perror("cannot create listening socket");
return 1;
}

/* 填充关于服务器的套节字信息 */
memset(&srv_addr, 0, sizeof(srv_addr));
srv_addr.sin_family=AF_INET;
srv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
srv_addr.sin_port=htons(PORT);


/* 将服务器和套节字绑定 */
ret = bind(listen_fd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));
if (ret == -1)
{
perror("cannot bind server socket");
close(listen_fd);
return 1;
}

/* 监听指定端口,连接5个客户端 */
ret = listen(listen_fd,5);
if (ret == -1)
{
perror("cannot listen the client connect request");
close(listen_fd);
return 1;
}

while(1)
{
len = sizeof(clt_addr);
com_fd = accept(listen_fd, (struct sockaddr *)&clt_addr, &len);
if (com_fd<0)
{
if (errno == EINTR)
{
continue;
}
else
{
perror("cannot accept client connect request");
close(listen_fd);
return 1;
}
}
/* 打印建立连接的客户端产生的套节字 */
printf("com_fd=%d\n", com_fd);
if ((pthread_create(&tid,NULL,server_client,&com_fd))==-1)
{
perror("pthread_create error");
close(listen_fd);
close(com_fd);
return 1;
}
}
return 0;
}


//线程执行函数负责读写
void *server_client(void *arg)
{
int size,j;
int operation;
  int server_type,recv_buf,call_buf;
int *parg = (int *)arg;
int new_fd = *parg;

printf("new_fd=%d\n",new_fd);

/* 每创建一个线程时:读取一个数字,确认为哪个客户端服务 */
  read(new_fd,&server_type,sizeof(server_type));

if (server_type == FROM_GET_NUM) 
{<