⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatserver.c

📁 linux网络程序设计 几个小程序以及编译命令
💻 C
字号:
//程序比较简单,就全放在一个文件里了//服务器维护一个用户列表,包括用户名和IP//响应用户加入和离开请求.//有新加入的用户或有用户离开,都要通知所有用户更新其用户列表#include <stdio.h>#include <time.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/types.h>#include <arpa/inet.h>#include <string.h>#include <signal.h>#include <pthread.h>#define SERV_PORT 7000#define SUDP_PORT 7001//#define CLET_PORT 2029#define MESG_PORT 7002#define SEG_SIZE  5000#define err_sys printf#define MAXSIZE 1024#define NAMELEN   20#define LEN sizeof(user)typedef  struct _user{    char name[NAMELEN];    char ip[16];    struct _user *next;    struct _user *prev;}user;static user *head;user *tail;user *p;user *q;int lock;int usrnum;void add(char * name,char *ip){    int i;    while(lock==1)    i++;    lock=1;    if(head==NULL)    {        p=tail=head=(user *)malloc(LEN);        head->prev=head->next=NULL;    }    else     {        p=(user *)malloc(LEN);        tail->next=p;        p->prev=tail;        p->next=NULL;        tail=p;    }    strcpy(p->name,name);    strcpy(p->ip,ip);    usrnum++;}void UserList(){    int i;    while(lock==1)    i++;    lock=1;    if(head==NULL)    {        printf("\nNo User now!\n\n");        return;    }    printf("The  user  list:\n\n");    printf("\tName");    printf("\t\t\t  IP\n");    for(p=head;p!=NULL;p=p->next)    {        printf("\t%-15s",p->name);        printf("%-20s\n",p->ip);    }    fflush(stdout);    lock=0;}user *find(char *buf,int i){    p=head;    while(p!=NULL)    {        if(strcmp((i==1)?p->ip:p->name,buf)==0)        return p;        p=p->next;    }    return NULL;}void del(char *buf){    int i;    while(lock==1)    i++;    lock=1;    user *result=find(buf,1);    if(result==NULL)    return;    if(head==NULL)    return;    if(result==head)    {        head=result->next;        if(head!=NULL)        head->prev=NULL;        else        tail=NULL;    }    else if(result==tail)    {        tail=result->prev;        tail->next=NULL;    }    else    {        result->prev->next=result->next;        result->next->prev=result->prev;    }    free(result);}sendmessage(int type,char *ip,char *name){    int sockfd;    int len;    struct sockaddr_in servaddr;    char buf[50];    memset(buf,0,50);    if(type==0)    {        strcpy(buf,"+");        strcat(buf,name);        strcat(buf,"\r");        strcat(buf,ip);        strcat(buf,"\r\r");    }    else    {        strcpy(buf,"-");        strcat(buf,ip);        strcat(buf,"\r");    }    for(p=head;p!=NULL;p=p->next)    {        bzero(&servaddr, sizeof(servaddr));        servaddr.sin_family = AF_INET;        servaddr.sin_port = htons(MESG_PORT);        inet_aton(p->ip,&servaddr.sin_addr);        sockfd = socket(AF_INET, SOCK_DGRAM, 0);        if(strcmp(ip,p->ip)==0)        continue;        len=sizeof(servaddr);        sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&servaddr,len);    }    close(sockfd);}void sendall(int sock,struct sockaddr_in * pservaddr){    char buf[5000];    int len;    memset(buf,0,5000);    buf[0]='\0';    if(head!=NULL)    for(p=head;p!=NULL;p=p->next)    {                strcat(buf,p->name);        strcat(buf,"\r");        strcat(buf,p->ip);        strcat(buf,"\r\r");    }    len=sizeof(*pservaddr);    sendto(sock,buf,sizeof(buf),0,(struct sockaddr *)pservaddr,len);  }//监听用户的加入消息void* tcplisten(void){    struct sockaddr_in	cliaddr, servaddr;    socklen_t		clilen;    int					listenfd;    listenfd = socket(AF_INET, SOCK_STREAM, 0);    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family      = AF_INET;    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);    servaddr.sin_port        = htons(SERV_PORT);    bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));    listen(listenfd, 5);    char    name[NAMELEN];    char           ip[16];    int connfd;    int buflen;    while(1)    {        memset(name,0,sizeof(name));        memset(ip,0,sizeof(ip));        clilen = sizeof(cliaddr);        bzero(&cliaddr, sizeof(cliaddr));        connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);        memset(name,0,NAMELEN);        buflen=recv(connfd,name,NAMELEN,0);        strcpy(ip,inet_ntoa(cliaddr.sin_addr));	  	        if(strlen(name)==0)        continue;        printf("\nA new comer :\n\t%s\t%s\n",name,ip);        fflush(stdout);             add(name,ip);        lock=0;        sendall(connfd,&cliaddr); //所有用户信息发送到新加入的user        sendmessage(0,ip,name);   //通知所有用户,有new comer        close(connfd);             //tcp连接结束    }}//udp监听用户的离开消息void *udplisten(void){    int sock;    struct sockaddr_in servaddr, cliaddr;    sock = socket(AF_INET, SOCK_DGRAM, 0);    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);    servaddr.sin_port = htons(SUDP_PORT);     if(bind(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)    {        perror("bind error");        exit(1);    }    int len;    char buf[1];    char ip[16];    while(1)    {        memset(buf,0,1);               bzero(&cliaddr,sizeof(cliaddr));         len = sizeof(cliaddr);        len=recvfrom(sock,buf,1, 0,(struct sockaddr *)&cliaddr,&len);        if(buf[0]=='-')        {            strcpy(ip,inet_ntoa(cliaddr.sin_addr));            p=find(ip,1);            fflush(stdout);            if(p==NULL)            printf("This user is not in the session,maybe in the last one!\n");            else            printf("\n%s has Left!\t \tIP: %s\n",p->name,p->ip);            fflush(stdout);            del(ip);            lock=0;            sendmessage(1,ip,NULL);  //通知所有用户有人离开        }    }}//主程序响应用户输入int main(int argc, char **argv){    int ret;    tail=head=NULL;    usrnum=0;    lock=0;    pthread_t tcplisten_t;    pthread_t udplisten_t;    ret=pthread_create(&tcplisten_t,NULL,(void *)tcplisten,NULL);     ret=pthread_create(&udplisten_t,NULL,(void *)udplisten,NULL);     int choice;         while(1)    {        printf("\nChat Server is running!");        printf("\nPlease input your choice:\n1.Show all user \n2.stop the server\n");        fflush(stdout);        scanf("%d",&choice);               getchar();        if(choice==1)        {            UserList();                    }        else        {            //先清理结构           pthread_cancel(tcplisten_t);           pthread_cancel(udplisten_t);           printf("the chat servert is stopped!\n\n");           exit(0);        }//else    }//while}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -