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

📄 s.c

📁 这是我自己写的用c语言的聊天室
💻 C
字号:
/*	s.c A chat server by Ze Zhang and Johannes Detlefsen	compile: gcc -o s s.c list.c -lpthread*/#include <stdio.h>#include <stdlib.h>		// for atoi() function#include <sys/socket.h>#include <sys/types.h>#include <errno.h>#include <netdb.h>#include <string.h>#include <sys/wait.h>#include <pthread.h>		// for the cosy POSIX threads#include <arpa/inet.h>		// for inet_ntoa() function#include <fcntl.h>#include <unistd.h>#include <sys/msg.h>#include "list.h"		// linked list to save socket file descriptors in it#define BACKLOG 10		// connections on the queue#define MAXDATALEN 1024#define PORT 9034/*initialize list*/	List L;    //Position P; //better declare local	pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;void * server(void * arg);int main( int argc, char *argv[] ) {	int sockfd,new_fd; // listen on sock_fd, new connection on new_fd	int portnum;	struct sockaddr_in server_addr;	struct sockaddr_in client_addr;	int sin_size;	pthread_t thread_id;	int sfd; /* socket file descriptor in the linked list*/	Position P;	/*check if portnumber is received by argument, if not use defined */	if( argc == 2 )	portnum = atoi(argv[1]);	 else portnum = PORT;	/*set up linked list to store the socket file descriptors */	L = MakeEmpty( NULL );	P = Header( L );	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {            perror("socket");            exit(1);	}	/* initialize the server_addr */	server_addr.sin_family=AF_INET;	server_addr.sin_addr.s_addr = INADDR_ANY; // here we get our IP address of www.tec.hkr.se	server_addr.sin_port=htons(portnum);	memset(&(server_addr.sin_zero), '\0', 8); // zero the rest of the struct	/* bind the port to the socket */	if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))== -1) {		perror("bind");		exit(1);	}	/* listen if anyone connecting to the port*/	if (listen(sockfd, BACKLOG) == -1) {            perror("listen");            exit(1);        } 	else printf("server is running now!\nPlease exit after all connections closed with Ctrl-c \n");	while(1){		sin_size=sizeof(struct sockaddr_in);		if ((new_fd = accept(sockfd, (struct sockaddr *)&client_addr,&sin_size)) == -1) {			perror("accept");			continue;		}	printf("new connection accepted\n");	  /* store new file descriptors in linked list */		//sfd=new_fd;		pthread_mutex_lock(&mutex);		printf("mutex lock aquired for INSERT\n");		P = Header( L );		Insert( new_fd, L, P );	//printf("Inserted sfd -%d- on the list\n",sfd);	  	P = Advance( P );		//go to next one		PrintList( L );		pthread_mutex_unlock(&mutex);		printf("mutex INSERT unlock\n");	  printf("server got connection from %s\n",inet_ntoa(client_addr.sin_addr));	  pthread_create(&thread_id,NULL,server,(void*)&new_fd);	  // pthread_join(thread_id,NULL); say: thread attribute is detached!!!	  pthread_detach(thread_id); /* now we never ever have to wait for this one anymore	  it's easier (less code) do change a joinable thread into detached state than creating	  a detached thread... */  	}  DeleteList( L );	// clean up linked list  close(sockfd);	// close Socket}/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx** Server function starts for every connected Client**xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/void * server(void * arg){  int msglen;  char	*buffer =(char *) malloc(MAXDATALEN),  	*msg    =(char *) malloc(MAXDATALEN),	*termmsg=(char *) malloc(30);  char	dpchar[]=": ", *strp;  char usrname[10];  int ts_fd,termlen;  ts_fd = * (int *) arg; 	/* get thread-socket file descriptor*/  int sfd; 			/* socket file descriptor in the linked list*/	Position P;  if(recv(ts_fd,usrname,MAXDATALEN,0) == -1){      printf("error: could not recv usrname!\n");	  exit(1);  }	else printf("%s connected to the server\n",usrname);	while(1){	 recv(ts_fd,buffer,MAXDATALEN,0);	 /* termination control */	 if ( strncmp( buffer, "/q", 2) == 0 ){		printf("%s has left the chat\n",usrname);		strcpy(termmsg,usrname);		strp=termmsg;		strp=strp+(strlen(termmsg));		strcpy(strp," has left the chat");		termlen=strlen(termmsg);		pthread_mutex_lock(&mutex);		printf("mutex lock aquired for DELETE\n");		Position P = Header( L );        	do{	// delete socket file descriptor from linked list            		P = Advance( P );            		sfd = Retrieve( P ); //read from list!			if(sfd == ts_fd) Delete( sfd, L );			if(sfd != ts_fd) send(sfd,termmsg,termlen,0);        	} while( !IsLast( P, L ) );		PrintList( L );		/*if( IsEmpty( L ) ){			L = MakeEmpty( NULL );			P = Header( L );		}*/		pthread_mutex_unlock(&mutex);		printf("mutex DELETE unlock \n");		close(ts_fd);		 break;	 }	strcpy(msg,usrname);	strp=msg;	strp=strp+(strlen(msg));	strcpy(strp,dpchar);	strp+=2; // move pointer 2 forward because dpchar contains ": "	strcpy(strp,buffer);	msglen=strlen(msg);	//if(send(ts_fd,msg,msglen,0)>0) 	printf("msg -%s- send\n",msg);	/* send msg to all clients: */	pthread_mutex_lock(&mutex);	printf("mutex lock aquired for SEND\n");	Position P = Header( L );        do{            P = Advance( P );            sfd = Retrieve( P ); //read from list!			//if(sfd != ts_fd)			send(sfd,msg,msglen,0);        } while( !IsLast( P, L ) );	PrintList( L );	pthread_mutex_unlock(&mutex);	printf("mutex SEND unlock\n");   };     return 0;}/*	Is the linked list a CRITICAL SECTION indeed?	Do we need to protect the linked list with MUTEX, CONDVAR or Semaphores ?*/

⌨️ 快捷键说明

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