1.聊天室
1.1服务器
#include <myhead.h>
#define SER_PORT 8888
#define SER_IP "192.168.174.128"struct msg
{char type;char usrname[20];char msgtext[1024];
};int main(int argc, const char *argv[])
{int sfd = socket(AF_INET,SOCK_STREAM,0);if (sfd==-1){ERRLOG("socket");}int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))==-1){perror("setsockopt error");return -1;}struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_PORT);sin.sin_addr.s_addr=inet_addr(SER_IP);if (-1==bind(sfd,(struct sockaddr*)&sin,sizeof(sin))){ERRLOG("bind");}if (-1==listen(sfd,128)){ERRLOG("listen");}struct sockaddr_in cin;socklen_t addrlen =sizeof(cin);fd_set readfds;FD_ZERO(&readfds);FD_SET(0,&readfds);FD_SET(sfd,&readfds);fd_set tempfds;char wbuf[128]="";struct sockaddr_in cin_arr[1024];int new_fd=-1;int maxfd=sfd;printf("---------服务器----------\n");while (1){tempfds=readfds;int res=select(maxfd+1,&tempfds,NULL,NULL,NULL);if (res==-1){ERRLOG("select");}else if (res==0){printf("timeout\n");return -2;}if (FD_ISSET(sfd,&tempfds)){new_fd=accept(sfd,(struct sockaddr*)&cin,&addrlen);if (new_fd==-1){ERRLOG("accept");}FD_SET(new_fd,&readfds);cin_arr[new_fd]=cin;if (new_fd>maxfd){maxfd=new_fd;}}if(FD_ISSET(0, &tempfds)){scanf("%s", wbuf);printf("触发终端输入事件:%s\n", wbuf);//讲消息发送给所有的客户端for(int i=4; i<=maxfd; i++){send(i, wbuf, strlen(wbuf), 0);}}for (int i=4;i<=maxfd;i++){if (!FD_ISSET(i,&tempfds)){continue;}struct msg msgbuf;int ret=recv(i,&msgbuf,sizeof(msgbuf),0);if (ret==0){printf("-----%s退出聊天室-------\n",msgbuf.usrname);char quit[128]="------";strcat(quit,msgbuf.usrname);strcat(quit,"退出聊天室---------\n");for (int j=4; j<=maxfd;j++ ){if (j!=i&&FD_ISSET(j,&readfds)){send(j,quit,strlen(quit),0);}}close(i);FD_CLR(i,&readfds);for (int k=maxfd;k>=0 ;k-- ){if (FD_ISSET(k,&readfds)){maxfd=k;break;}}break;}if (ret==-1){close(i);ERRLOG("recv");}if (msgbuf.type=='l'){printf("-----%s进入聊天室-------\n",msgbuf.usrname);char enter[128]="------";strcat(enter,msgbuf.usrname);strcat(enter,"进入聊天室---------\n");for (int j=4; j<=maxfd;j++ ){if (j!=i&&FD_ISSET(j,&readfds)){send(j,enter,strlen(enter),0);}}}if (msgbuf.type=='c'){printf("------%s------:发送了一条信息\n",msgbuf.usrname);char sbuf[128]="---";strcat(sbuf,msgbuf.usrname);strcat(sbuf,"---:");strcat(sbuf,msgbuf.msgtext);for (int j=4; j<=maxfd;j++ ){if (j!=i&&FD_ISSET(j,&readfds)){send(j,sbuf,strlen(sbuf),0);}}}if (msgbuf.type=='q'){printf("-----%s退出聊天室-------\n",msgbuf.usrname);char quit[128]="------";strcat(quit,msgbuf.usrname);strcat(quit,"退出聊天室---------\n");for (int j=4; j<=maxfd;j++ ){if (j!=i&&FD_ISSET(j,&readfds)){send(j,quit,strlen(quit),0);}}close(i);FD_CLR(i,&readfds);for (int k=maxfd;k>=0 ;k-- ){if (FD_ISSET(k,&readfds)){maxfd=k;break;}}break;}}}close(sfd);return 0;
}
1.2客户端
#include <myhead.h>
#define SER_PORT 8888
#define SER_IP "192.168.174.128"
struct msg
{char type;char usrname[20];char msgtext[1024];
};
void *fun(void *arg)
{ int sfd = *(int *)arg;while (1){char buf[1100];int ret = recv(sfd, buf, sizeof(buf) - 1, 0); // 留一个位置给字符串结束符if (ret == 0){printf("服务器已关闭..\n");break;}else if (ret == -1){perror("recv error");break;}buf[ret] = '\0'; printf("%s", buf);fflush(stdout);}pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{int sfd = socket(AF_INET,SOCK_STREAM,0);if (sfd==-1){ERRLOG("socket");}struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_PORT);sin.sin_addr.s_addr=inet_addr(SER_IP);if (-1==connect(sfd,(struct sockaddr*)&sin,sizeof(sin))){ERRLOG("connect");}struct msg msgbuf;msgbuf.type='l';printf("请输入姓名:");fgets(msgbuf.usrname,sizeof(msgbuf.usrname),stdin);msgbuf.usrname[strlen(msgbuf.usrname)-1] = 0;strcpy(msgbuf.msgtext,"\0");send(sfd,&msgbuf,sizeof(msgbuf),0);pthread_t tid;if (0!=pthread_create(&tid,NULL,fun,&sfd)){printf("pthread_create error\n");return -1;}pthread_detach(tid);printf("欢迎进入聊天室,退出请输入quit...\n");while (1){fgets(msgbuf.msgtext,sizeof(msgbuf.msgtext),stdin);if (strcmp(msgbuf.msgtext,"quit\n")==0){msgbuf.type='q';send(sfd,&msgbuf,sizeof(msgbuf),0);break;}else{msgbuf.type='c';send(sfd,&msgbuf,sizeof(msgbuf),0);}}return 0;
}