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

📄 c.c

📁 这是我自己写的用c语言的聊天室
💻 C
字号:
/*
	c.c A chat client from Ze Zhang and Johannes Detlefsen
	compile: gcc -o c c.c -lncurses -lpthread
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>		// for the inet_ntoa() function
#include <sys/socket.h>		// for a convenient realization of IPC
#include <ncurses.h>		/* for the nice windows */
#include <pthread.h>		// for the cosy POSIX threads

#define PORT 9034 // the port client will be connecting to
#define WWW "www.tec.hkr.se"
#define MAXLEN 100 // max number of bytes we can get at once
#define MAX 10 // max number of chars in username string

	void * readmsg(void * arg);
	void * writemsg(void * arg);

	int sockfd;
	WINDOW *win_read;
	WINDOW *win_write;
	//WINDOW *win_usrs; // not implemented function of online user's names display

void loginwin(){
	WINDOW *win_login;
	int h,w,usernamelength;
	char username[MAX]=" \0", *usr;

	initscr();
	cbreak();
	refresh();
	getmaxyx(stdscr,h,w);

	win_login = newwin(3,19,h/2-3,w/2-10);
	box(win_login,0,0);
	mvwprintw(win_login,1,1,"login: ");
	wrefresh(win_login);
	mvwgetnstr(win_login,1,8,username,MAX);
	(char *) usr = username;
	usernamelength = strlen(username);
	send(sockfd,usr,usernamelength,0);
	wrefresh(win_login);
	delwin(win_login);
}

void chatwin(){
	int h,w;
	WINDOW *win_box;
	getmaxyx(stdscr,h,w);

	win_box = newwin(h-6,w,1,0);
	box(win_box,0,0);
	mvwprintw(win_box,0,5," Output Window ");
	wrefresh(win_box);

	win_read = newwin(h-8,w-2,2,1);
	scrollok(win_read,TRUE);
	wrefresh(win_read);

	win_write = newwin(3,w,h-5,0);
	box(win_write,0,0);
	mvwprintw(win_write,0,5," Input Window ");
	mvwprintw(win_write,0,20," type /q to exit ");
	wrefresh(win_write);

	/*win_usrs = newwin(h-6,20,1,w-20);
	box(win_usrs,0,0);
	scrollok(win_usrs,TRUE);
	mvwprintw(win_usrs,0,2," Users Online ");
	wrefresh(win_usrs);*/
}

int main( int argc, char *argv[] )
{
	struct hostent *he;
	struct sockaddr_in server_addr; // connector's address information
	int portnum;
	pthread_t thread_id1;
	pthread_t thread_id2;

	/* if portnumber is not given by argument use defined (9034)  */
	if( argc == 2 )	portnum = atoi(argv[1]);
	 else portnum = PORT;

	if ((he=gethostbyname(WWW)) == NULL) {  // get the host info
        	perror("gethostbyname");
        	exit(1);
	}

 	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
 		perror("socket");
 		exit(1);
	}
	//else printf("The Socket was created\n");

    server_addr.sin_family = AF_INET;    // host byte order
    server_addr.sin_port = htons(portnum);  // short, network byte order
    server_addr.sin_addr = *((struct in_addr *)he->h_addr);
    memset(&(server_addr.sin_zero), '\0', 8);  // zero the rest of the struct

	if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
		perror("connect");
		exit(1);
	}

	if(initscr()==NULL){ // initialize ncurses WINDOW (stdscr)
		printf("could not initialize ncurses Window");
		exit(1);
	}
	printw("client connected to %s\n",inet_ntoa(server_addr.sin_addr));
	loginwin();	// input username and send it to server
	chatwin();	// initialize chat windows
	pthread_create(&thread_id1,NULL,readmsg,NULL);
	pthread_create(&thread_id2,NULL,writemsg,NULL);
	pthread_join(thread_id1,NULL);
	pthread_join(thread_id2,NULL);

	/* since the socket file descriptor is full duplex
	   there is no need to protect him with mutex */

	close(sockfd);
    return 0;
}

void * readmsg(void * arg){
	char buf[MAXLEN];
	int numbytes;
	wmove(win_read,0,0);
	while(1){ // loop to constantly recv and read msgs, terminated by exit in writemsg()

     /*if ((numbytes=recv(sockfd, buf, MAXLEN-1, 0)) == -1) {
            perror("recv");
            exit(1);     }*/

	if ( (numbytes=recv(sockfd, buf, MAXLEN-1, 0)) > 0 ) { // if message received print it out

	    buf[numbytes] = '\0';

		wprintw(win_read,"%s\n",buf);		//mvwprintw(win_read,y,1,"%s",buf);
		wrefresh(win_read);
	}
 };
}

void * writemsg(void * arg){

	int bufsize,i,h,w;
	char *buffer = (char *) malloc(MAXLEN);
	getmaxyx(stdscr,h,w);
	//noecho();
	while(1){ // loop to send msgs, terminated with exit by /q

	for(i=18;i<=w-3;i++) mvwprintw(win_write,1,i," ");
   	wrefresh(win_write);
	mvwprintw(win_write,1,1,"Message to send: ");
	wrefresh(win_write);
	mvwgetnstr(win_write,1,18,buffer,w-21); // read input msg
		
	if ( strncmp( buffer, "/q", 2) == 0 ){  /* close and exit( 0 ) condition */
		send(sockfd,"/q",2,0); // send /q termination msg to server
		refresh();
		delwin(win_read);
		delwin(win_write);
		//delwin(win_usrs);
		endwin();
		printf("terminating gracefully - goodbye and have a nice day!\n");
		close(sockfd);
		exit(0);
	}

	bufsize=strlen(buffer)+1;
	send(sockfd,buffer,bufsize,0);
	};
}

// Do we need a mutex protection for the socket-file-descriptor??? no because it's full duplex

⌨️ 快捷键说明

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