serv.c
#include#include #include #include #include #include #include #include #include int serverfd;//服务器socket int clientfd[100];//客户端的socketfd,100个元素,clientfd[0]~clientfd[99] int size =50;//用来控制进入聊天室的人数为50以内 char* IP = "127.0.0.1";//主机ip地址 short PORT = 6666;//端口号 typedef struct sockaddr meng; time_t nowtime; void init(){ serverfd = socket(PF_INET,SOCK_STREAM,0); if (serverfd == -1){ perror("创建socket失败"); exit(-1);} //为套接字设置ip协议 设置端口号 并自动获取本机ip转化为网络ip struct sockaddr_in addr;//存储套接字的信息 addr.sin_family = PF_INET;//地址族 addr.sin_port = htons(PORT);//设置server端端口号,你可以随便设置,当sin_port = 0时,系统随机选择一个未被使用的端口号 addr.sin_addr.s_addr = inet_addr(IP);//把127.0.0.1改为自己的server端的ip地址,当sin_addr = INADDR_ANY时,表示从本机的任一网卡接收数据 //绑定套接字 if (bind(serverfd,(meng*)&addr,sizeof(addr)) == -1){ perror("绑定失败"); exit(-1); } if (listen(serverfd,100) == -1){//监听最大连接数 perror("设置监听失败"); exit(-1); } } void SendAll(char* msg){ int i; for (i = 0;i < size;i++){ if (clientfd[i] != 0){ printf("发送给%dn",clientfd[i]); printf("发送的信息是: %sn",msg); //写入文件 char buf[1024]; FILE *logs = fopen("log.txt", "a+"); if(logs== NULL) { printf("open file erroe: n"); } else{ time(&nowtime); sprintf(buf, "进入时间:%stIP地址:%sn",ctime(&nowtime),IP); fputs(buf,logs); sprintf(buf, "所发信息:%sn",msg); fputs(buf,logs); fclose(logs); } send(clientfd[i],msg,strlen(msg),0); } } } void* server_thread(void* p){ int fd = *(int*)p; int i,ll; char buf[100] = {}; printf("pthread = %dn",fd); while(1){ if ((ll=recv(fd,buf,sizeof(buf),0))<= 0){ for (i = 0;i < size;i++){ if (fd == clientfd[i]){ clientfd[i] = 0; break; } } printf("退出:fd = %d 退出了。n",fd); char buf[1024]; FILE *logs = fopen("log.txt", "a"); if(logs== NULL) { printf("open file erroe: n"); } else{ time(&nowtime); sprintf(buf, "退出时间:%stIP地址:%sn",ctime(&nowtime),IP); fputs(buf,logs); } pthread_exit(0); } //把服务器接受到的信息发给所有的客户端 buf[ll]=0; SendAll(buf); } } void server(){ printf("服务器启动n"); while(1){ struct sockaddr_in fromaddr; socklen_t len = sizeof(fromaddr); int fd = accept(serverfd,(meng*)&fromaddr,&len); //调用accept进入堵塞状态,等待客户端的连接 if (fd == -1){ printf("客户端连接出错...n"); continue; } int i = 0; for (i = 0;i < size;i++){ if (clientfd[i] == 0){ //记录客户端的socket clientfd[i] = fd; printf("线程号= %dn",fd);// //有客户端连接之后,启动线程给此客户服务 pthread_t tid; pthread_create(&tid,0,server_thread,&fd); break; } if (size == i){ //发送给客户端说聊天室满了 char* str = "对不起,聊天室已经满了!"; send(fd,str,strlen(str),0); close(fd); } } } } int main(){ init(); server(); }
sem_thr2.c
#include#include #include #include #include #include #include #include #define SEM "prt" #define CLEAR() printf(" 33[2J") #define MOVETO(x,y) printf(" 33[%d;%dH", (x), (y)) int lock_var,xid=1,val; time_t end_time; sem_t *sem; void *pthread1(int *x); void print(); int main(int argc, char *argv[]) { pthread_t id[6]; pthread_t mon_th_id; int ret=0,num; end_time = time(NULL)+48; puts("Plaese input NUM:"); scanf("%d",&num); sem=sem_init(SEM,0,1); // system("clear"); CLEAR(); while(ret time(NULL)) { print(); sleep(1); } MOVETO(28,16); puts("---Main线程--END---n"); // pthread_join(id2,NULL); exit(0); } void *pthread1(int *x) { int i,n,v; char disp[120]; memset(disp,0,120); n=*x; // while(time(NULL) < end_time){ MOVETO(n*4,4); printf("线程ID号=%u, 第 %d 号线程开始运行!。。。n",pthread_self(),*x); for(i=0;i<20-n;i++){ sem_wait(sem); //print(n,i); MOVETO(n*4+2,4); sem_getvalue(sem,&v); printf("===>>第 %d 号线程%d次进入临界区操作,信号量值=%d n", n,i,v); if(n%2==1) { strcat(disp,"###");MOVETO(n*4+1,4); puts(disp); } else { strcat(disp,"**");MOVETO(n*4+1,4); puts(disp);} //close(stdout); sem_post(sem); if(n%2==1) sleep(1); else sleep(2); } // printf("pthread1:lock_var=%dn",lock_var); MOVETO(n*4+2,4); printf("===>>线程ID号=%u, 第 %d 号线程已正常结束!。。。n",pthread_self(), n); //sleep(1); } void print() { time_t tmp; // struct tm *tmp_ptr = NULL; // time(&tmpcal_ptr); time(tmp); 两种取值方法均可以 // printf("tmpcal_ptr=%dn", tmpcal_ptr); sem_wait(sem); MOVETO(1,32); // tmp_ptr = gmtime(&tmpcal_ptr); printf(" %s n",ctime(&tmp)); sem_post(sem); }
client.c
#include#include #include #include #include #include #include #include #include int clientfd2; //客户端socket char* IP = "127.0.0.1"; //服务器的IP short PORT = 6666; //服务器服务端口 typedef struct sockaddr meng; char name[30]; //设置支持的用户名长度 time_t nowtime; void* recv_thread(void*); void init(){ clientfd2 = socket(PF_INET,SOCK_STREAM,0);//创建套接字 struct sockaddr_in addr; //将套接字存在sockaddr_in结构体中 addr.sin_family = PF_INET; //地址族 addr.sin_port = htons(PORT);//端口号 可随意设置,不过不可超过规定的范围 addr.sin_addr.s_addr = inet_addr(IP);//inet_addr()函数将点分十进制的字符串转换为32位的网络字节顺序的ip信息 //发起连接 if (connect(clientfd2,(meng*)&addr,sizeof(addr)) == -1){ perror("无法连接到服务器"); exit(-1); } printf("客户端启动成功n"); } void start(){ pthread_t id; //创建一个线程用于数据的接收,一个用于数据的发送 pthread_create(&id,0,recv_thread,0); char buf2[100] = {}; sprintf(buf2,"%s进入了群聊",name); time(&nowtime); printf("进入的时间是: %sn",ctime(&nowtime)); send(clientfd2,buf2,strlen(buf2),0); char buf[100] = {}; char msg[100] = {}; while(1){ gets(buf); sprintf(msg,"%s发送的信息是:%s",name,buf); send(clientfd2,msg,strlen(msg),0); if (strcmp(buf,"quit") == 0){ memset(buf2,0,sizeof(buf2));//初始化 sprintf(buf2,"%s退出了群聊",name); send(clientfd2,buf2,strlen(buf2),0); break; } } close(clientfd2); } void* recv_thread(void* p){ int ll; char buf[100] = {}; while(1){ if ((ll=recv(clientfd2,buf,sizeof(buf),0)) <= 0) break; buf[ll]=0; printf("%sn",buf); } exit(1); } int main(){ init(); printf("请输入用户名:"); scanf("%s",name); printf("nn*****************************n"); printf("欢迎%s 进入群聊n",name); printf(" 输入quit 退出n"); printf("n*****************************nn"); start(); return 0; }



