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

📄 winio.c

📁 在linux系统下实现了一个多人聊天工具的服务器端和客户端。该工具支持显示在线用户
💻 C
字号:
#include <termios.h>
#include <term.h>
#include <curses.h>
#include <stdio.h>
#include <stdlib.h>

#include "global.h"

#define MAX_LINE	100
struct termios oldterm;		/*The user's original term settings*/

/*convert a string to an integer*/
int get_int(char * str)
{
	int i = 0;
	int j = 0;
	char digit[20];
	while(str[i]&&!isdigit(str[i]))
		i++;
	while(isdigit(str[i]))
		digit[j++] = str[i++];
	if(j == 0)
		return -1;
	digit[j] = '\0';
	i = atoi(digit);
	return i;
}

/*do some initialization of the windows*/
/*three windows*/
void window_ini()
{
	int i = 0;
	char message[] = "The window is too small,please make it larger";
	char temp[] = "Press <C-S> to send message:";
	if((showwinrows = LINES-MIN_EDITOR_ROWS-1)<MIN_SHOW_ROWS) {
		fprintf(stderr,"%s\n",message);
		exit(1);
	}
	    //showErrorM(message);
	/* Setup the show window*/
	showwin = newwin(showwinrows, COLS, 0, 0);
	/* Setup the main edit window */
	editwin = newwin(MIN_EDITOR_ROWS,COLS,showwinrows+1,0);
	/* Setup the middle window*/
	midwin = newwin(1,COLS,showwinrows,0);

	wclear(showwin);
	wclear(editwin);
	wclear(midwin);
	wattron(midwin,A_REVERSE);
	if(COLS > 28) {
		for(i = 0; i < 28; i++)
			mvwaddch(midwin,0,i,temp[i]);
		for(;i < COLS; i++)
			mvwaddch(midwin,0,i,' ');
	} else {
		for(i = 0; i < COLS; i++) 
		    mvwaddch(midwin,0,i,' '); 
	}
	wattroff(midwin,A_REVERSE);
	wrefresh(midwin);
	wrefresh(editwin);
	keypad(editwin, TRUE);
	keypad(editwin,TRUE);
}

/*let the setting of term retun to the old one*/
void finish()
{
    nocbreak();
    nl();
    echo();
    endwin();
    noraw();

    /* Restore the old term settings */
    tcsetattr(0, TCSANOW, &oldterm);

    exit(0);
}

/*allocate some memory for the structure for the 
 * show window and do some initializaton of the 
 * associated pointers*/
void init_struct()
{
	int i;
	rnode * pre;
	rnode * p;
	if((top=(rnode *)malloc(sizeof(rnode)))==NULL) {
		fprintf(stderr,"malloc fail!\n");
		exit(1);
	}
	if((top->mes=(char *)malloc(MAX_LINE*sizeof(char)))==NULL) {
		fprintf(stderr,"malloc fail!\n");
		exit(1);
	}
	pre = top;
	for(i = 0; i < showwinrows; i++) {
		if((p=(rnode *)malloc(sizeof(rnode)))==NULL) {
			fprintf(stderr,"malloc fail!\n");
			exit(1);
		}
		if((p->mes=(char *)malloc(MAX_LINE*sizeof(char)))==NULL) {
			fprintf(stderr,"malloc fail!\n");
			exit(1);
		}
		pre->next = p;
		pre = p;
	}
	pre->next = top;
	bott = top;
	rowcount = 0;
}

/*destroy the show window structure*/
void destroy_struct()
{
	int i;
	rnode * pre;
	rnode * p;
	p = top;
	pre = top;
	for(i = 0; i < showwinrows-1; i++) {
		pre = p->next;
		free(p->mes);
		free(p);
		p = pre;
	}
	free(p->mes);
	free(p);
}


/*copy the message received from the server to the 
 * the structure in a special form*/
void insert_input(char * mes)
{
	int n;
	char * p;
	int l = 0;
	int j,k;
	p = mes;
	while(1) {
		n = strlen(p);
		if(n == 1 && p[0] == '\n')
			break;
		j = l+COLS;
		if(n > COLS) {
			j = l+COLS-1;
			while(mes[j]!=' '&&
			      j > l+COLS/2)
				j--;
			if(j == l+COLS/2)
				j = l+COLS-1;

		}
		k = 0;
		while(mes[l]&&j > l) {
			if(mes[l]=='\n') {
				l++;
				break;
			}
			bott->mes[k] = mes[l];
			k++;
			l++;
		}
		p = &mes[l];
		bott->mes[k] = '\0';
		if(show_line == showwinrows)
			top = top->next;
		else
			show_line++;
		bott = bott->next;
		if(!mes[l])
			break;
	}
}


/*display the message received from the server
 * in the show window*/
void display()
{
	int i = 0;
	rnode * p;
	p = top;
	while(p != bott) {
		mvwprintw(showwin,i,0,"%s\n",p->mes);
		i++;
		p = p->next;
	}
	wrefresh(showwin);
	wrefresh(editwin);
}


/*to see whether the message is an error message
 * and display the meaning of the message*/
void check_error(char *mes,int i)
{
	int k = 0;
	int j = 0;
	int err,n;
	char name[MAXNAME];

//	/*divide the message*/
//	while(mess_buffer[i][j]==' '||mess_buffer[i][j]=='\t')
//		j++;
//	if(mess_buffer[i][j] == '<') {
//		while(mess_buffer[i][j]&&mess_buffer[i][j]!='>')
//			mes[k++] = mess_buffer[i][j++];
//		if(mess_buffer[i][j]!='>') {
//			fprintf(stderr,"Unknown message!\n");
//			exit(1);
//		}
//		mes[k++] = '>';
//		mes[k++] = ' ';
//	}
//	while(mess_buffer[i][j]&&mess_buffer[i][j]!='\n')
//		j++;
//	if(mess_buffer[i][j]!='\n') {
//		fprintf(stderr,"Unacceptable message!\n");
//		exit(1);
//	}
//	j++;
//	while(mess_buffer[i][j]==' '||mess_buffer[i][j]=='\t')
//		j++;
	while(mess_buffer[i][j])
		mes[k++] = mess_buffer[i][j++];
	mes[k] = '\0';

	if(strncmp(mes,"ERR:",4)==0) {
		/*classify the error message*/
		err = get_int(&mes[4]);
		if(err > 0) {
			if(err == 101) {
				sprintf(mes,"server: nickname exists!\n");
				berror = 1;
			} else if(err == 102) {
				sprintf(mes,"server: command not supported!\n");
			} else if(err == 103) {
				sprintf(mes,"server: no such user!\n");
			} else if(err == 104) {
				fprintf(stderr,"max connections exhausted!\n");
				berror = 1;
			}
		}
	}
}



/*handle the input from the server and
 * display them*/
void * thread_display()
{
	int i;
	char mes[MAX_MES];
	
	while(1) {
		sem_wait(&full);
		sem_wait(&mutex);

		check_error(mes,mess_out);
		mess_out = (mess_out+1)%MAX_SHOW_BUFF;

		sem_post(&mutex);
		sem_post(&empty);

		insert_input(mes);
		display();
		if(enable_log) {
			do_log(mes);
		}
		if(berror) {
			sleep(1);
			finish();
			exit(1);
		}
	}
}

/*handle the screen input and output*/
void * thread_screen(void *arg)
{
	pthread_t tid_keyboard;
	pthread_t tid_display;
	struct termios term;
	int res;
	/*First back up the old settings so they can be restored*/
	tcgetattr(0, &oldterm);
	term = oldterm;
	term.c_cc[VINTR] = _POSIX_VDISABLE;
	term.c_cc[VQUIT] = _POSIX_VDISABLE;
	term.c_lflag &= ~IEXTEN;
	tcsetattr(0, TCSANOW, &term);
	/*now ncurses init stuff*/
	initscr();
	savetty();
	nonl();
	cbreak();
	noecho();
	raw();
	window_ini();
	init_struct();
	/*create two thread. one for the show window displaying
	 * the input message and the other one is used to handle
	 * the user input*/
	if((res=pthread_create(&tid_display,NULL/*&thread_attr*/,&thread_display,
	   NULL)) != 0) {
		fprintf(stderr,"Creating thread fail!\n");
		exit(1);
	}
	if((res=pthread_create(&tid_keyboard,NULL/*&thread_attr*/,&thread_keyboard,
	   NULL)) != 0) {
		fprintf(stderr,"Creating thread fail!\n");
		exit(1);
	}
	pthread_join(tid_display, NULL);
	pthread_join(tid_keyboard, NULL);
}

⌨️ 快捷键说明

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