Linux+C實現簡易聊天室

最近Linux網絡程序設計課程大作業,要求設計一個簡易的網絡聊天室,功能如下:

  • 網絡聊天室

功能要點:
(1)用戶管理:註冊、修改密碼;
(2)聊天室管理:用戶登錄、創建聊天室、設置聊天室密碼;
(3)聊天管理:在同一聊天室裏,用戶所發送的消息每位在線用戶都可以收到,也可以單獨給某位在線用戶發消息;可以查詢聊天室在線用戶信息;
(4)系統管理:顯示所有在線用戶;顯示所有聊天室;給所有在線用戶羣發消息;提供命令幫助,讓用戶瞭解命令的格式:
例如 send user1 message1表示給用戶user1發送消息message1等。

本人編程學的比較爛,但是還是勉強湊出了這些功能,在這也分享一下我的代碼,代碼是一小部分非原創,因爲是老師上課講的一部分代碼,剩下絕大部分均爲自己寫的,在這裏分享一下。

首先server.c

#include <stdio.h>
#include <stdlib.h>     // exit
#include <string.h>
#include <unistd.h>     // bind listen
#include <time.h>       // time(NULL)   ctime(&ticks)
#include <netinet/in.h>
#include <arpa/inet.h>  // 必須包含,用於inet_ntop
#include <pthread.h>

#define PORT 8000
#define MAXMEM 10
#define BUFFSIZE 128

//#define DEBUG_PRINT 1         // 宏定義 調試開關
#ifdef DEBUG_PRINT
#define DEBUG(format, ...) printf("FILE: "__FILE__", LINE: %d: "format"\n", __LINE__, ##__VA_ARGS__)
#else
#define DEBUG(format, ...)
#endif

FILE *fp;
int listenfd, connfd[MAXMEM];
struct client{			/* 結構體存儲一組用戶名和對應的套接字 */
	char name[20];		/* 用戶名 */
	int socket_name;	/* 套接字 */
	char chatroom[20]; 	/* 加入的聊天室 */
};
struct client info_class[MAXMEM];   /* 定義結構體數組 */

void quit();			/*輸入quit時退出服務器*/
void rcv_snd(int n);
void regist(int n);				/* 註冊賬戶 */
void login(int n);				/* 登錄 */
void create_chatroom(int n);	/* 創建聊天室函數 */
void join_chatroom(int n);		/* 加入聊天室函數 */
void show(int n);				/* 服務命令處理函數 */

int main()
{
    struct sockaddr_in serv_addr, cli_addr;
    int i;
    time_t ticks;
    pthread_t thread;
    char buff[BUFFSIZE];

    printf("running...\n(Prompt: enter command ""quit"" to exit server)\n");
    DEBUG("=== initialize...");     // 初始化填充服務端地址結構
    /*將server_addr指向內存的前sizeof(struct sockaddr_in)字節清零*/
    bzero(&serv_addr, sizeof(struct sockaddr_in));

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    DEBUG("=== socket...");
    /*socket 創建服務器端的監聽套接字*/
    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if(listenfd < 0)
    {
        perror("fail to socket");
        exit(-1);
    }

    DEBUG("=== bind...");
    /*bind 將套接字與填充好的地址結構進行綁定*/
    if(bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        perror("fail to bind");
        exit(-2);
    }

    DEBUG("=== listening...");
    /*listen 將主動連接套接字變爲被動傾聽套接字*/
    listen(listenfd, MAXMEM);

    /* === 創建一個線程,對服務器程序進行管理,調用quit函數 === */
    pthread_create(&thread, NULL, (void *)(quit), NULL);

    // 將套接字描述符數組初始化爲-1,表示空閒
    for(i=0; i<MAXMEM; i++)
        connfd[i] = -1;

    while(1)
    {
        int len;  		// = sizeof(cli_addr);
        for(i=0; i<MAXMEM; i++)
        {
            if(connfd[i] == -1)
                break;
        }
        // accept 從listen接受的連接隊列中取得一個連接
        connfd[i] = accept(listenfd, (struct sockaddr *)&cli_addr, &len);
        if(connfd[i] < 0)
        {
            perror("fail to accept");
            //      continue;       // 此句可以不用,accept會阻塞等待
        }
        ticks = time(NULL);
        //sprintf(buff, "%.24s\r\n", ctime(&ticks));
        printf("%.24s\n\tconnect from: %s, port %d\n",
               ctime(&ticks), inet_ntop(AF_INET, &(cli_addr.sin_addr), buff, BUFFSIZE),
               ntohs(cli_addr.sin_port));      // 注意 inet_ntop的使用,#include <arpa/inet.h>

        /* === 針對當前套接字創建一個線程,對當前套接字的消息進行處理 === */
        pthread_create(malloc(sizeof(pthread_t)), NULL, (void *)(&rcv_snd), (void *)i);
    }
    return 0;
}

void quit()
{
    char msg[10];
    while(1)
    {
        scanf("%s", msg);       // scanf 不同於fgets, 它不會讀入最後輸入的換行符
        if(strcmp(msg, "quit") == 0)
        {
            printf("Byebye... \n");
            close(listenfd);
            exit(0);
        }
    }
}

void rcv_snd(int n)
{
    int len, i;
    char  buf[BUFFSIZE] ,mytime[32], v[5];   /*v用接受服務命令字符*/
    time_t ticks;
    int ret;

    write(connfd[n], "---Service select(1/2)---\n\t1.User registration\n\t2.User login\n",
		  strlen("---Service select(1/2)---\n\t1.User registration\n\t2.User login\n"));
    len = read(connfd[n], v, 5);			/* 讀取客戶端輸入的1或者2命令 */
    if(len > 0)
        v[len-1] = '\0';     /* 去除換行符 */
    if(strcmp(v,"1") == 0){				/*如果選擇註冊服務*/
		strcpy(buf,"---User registration---\n");
		/*在客戶端顯示當前狀態*/
		write(connfd[n],buf,strlen(buf));
		regist(n);
    }else if(strcmp(v,"2") == 0){			/*如果選擇登錄服務*/
		strcpy(buf,"---User login---\n");
		/*在客戶端顯示當前狀態*/
		write(connfd[n],buf,strlen(buf));
		login(n);
	}
	else{
		write(connfd[n], "Invalid command, enter again.\n",
			strlen("Invalid command, enter again.\n"));
		rcv_snd(n);	/* 輸入其他值時重新進入服務選項 */
	}
	/* 登陸成功後服務提示,這裏就是大廳 */
	write(connfd[n], "---Service select(1/2/3/4)---\n\t1.Show online users\n\t2.Show all chatrooms\n\t3.Create a chatroom\n\t4.Join a chatroom\n",
		  strlen("---Service select(1/2/3/4)---\n\t1.Show online users\n\t2.Show all chatrooms\n\t3.Create a chatroom\n\t4.Join a chatroom\n"));
	show(n);

    while(1)
    {
        char temp[BUFFSIZE];
        char *str;
        if((len=read(connfd[n], temp, BUFFSIZE)) > 0)    // 檢查如果有消息
        {
            temp[len-1] = '\0';
            /* 當用戶輸入bye時,當前用戶退出 */
            if(strcmp(temp, "bye") == 0)
            {
                close(connfd[n]);
                connfd[n] = -1;
                pthread_exit(&ret);
            }
             else if(strcmp(temp, "help") == 0){
				memset(buf, 0, sizeof(buf));
				strcpy(buf, "\tYou can try these commands.\n");
				write(connfd[n], buf, strlen(buf));
				strcpy(buf, "[send to user1]: Send the following message to user1.\n");
				write(connfd[n], buf, strlen(buf));
				strcpy(buf, "[back]: Back to hall.\n");
				write(connfd[n], buf, strlen(buf));
				strcpy(buf, "[bye]: Exit the client.\n");
				write(connfd[n], buf, strlen(buf));
            }
            else if(strcmp(temp, "back") == 0){
				write(connfd[n], "---Service select(1/2/3/4)---\n\t1.Show online users\n\t2.Show all chatrooms\n\t3.Create a chatroom\n\t4.Join a chatroom\n",
				strlen("---Service select(1/2/3/4)---\n\t1.Show online users\n\t2.Show all chatrooms\n\t3.Create a chatroom\n\t4.Join a chatroom\n"));
				memset(info_class[n].chatroom, 0, sizeof(info_class[n].chatroom)); /* 返回大廳後即退出聊天室 */
				show(n);
            }
            /* 如果當前客戶端在聊天室內 */
            else if(strlen(info_class[n].chatroom) != 0){
				/* 如果發現關鍵字符串"send to",從聊天室轉入私聊程序段 */
				if((str = strstr(temp, "send to ")) != 0){
					int x;							/* 查找send to後跟用戶名的開始下標值 */
					char des[10];					/* 用來存儲目標用戶的名稱,從send to user中獲取 */
					x = strspn(temp, "send to ");	/* send to 後面用戶名字符串開始的索引 */
					strncpy(des, temp + x, strlen(temp)-x+1);
					strcat(des, "\n");
					for(i=0; i<MAXMEM; i++){
						if(strcmp(des, info_class[i].name) == 0){	/* 遍歷匹配user1的姓名 */
							while(1){
								if((len=read(connfd[n], temp, BUFFSIZE)) > 0){
									temp[len-1] = '\0';
									if(strcmp(temp, "back") == 0){	/* 如果收到back字段,則返回羣聊 */
										write(connfd[n], "You have returned the chatroom, send a message or use 'back' again.\n",
												strlen("You have returned the chatroom, send a message or use 'back' again.\n"));
										break;
									}
									else{
										ticks = time(NULL);
										strftime(mytime,sizeof(mytime),"[%H:%M:%S]",localtime(&ticks));
										strcpy(buf, mytime);  				// 顯示時間
										strcat(buf, "\t");
										strcat(buf, info_class[n].name);	// 顯示用戶名
										buf[strlen(buf)-1] = '\0';
										strcat(buf, ":\t");
										strcat(buf, temp);					// 客戶端消息內容
										strcat(buf, "\n");
										write(connfd[i], buf, strlen(buf));
										write(connfd[n], buf, strlen(buf));
									}
								}
							}
						}
					}
				}
				else if(strcmp(temp, "show member") == 0){		/* show member顯示聊天室內成員 */
					char member[50];
					strcpy(member, "---Current members---\n");
					for(int i=0; i<MAXMEM; i++)
					{
						if(strcmp(info_class[i].chatroom, info_class[n].chatroom) == 0){
							strcat(member, info_class[i].name);	/* 將在線用戶名添加到info */
						}
					}
					write(connfd[n], member, strlen(member));
				}
				else{  /* 不是私聊那就是在聊天室內羣發 */
					for(i=0; i<MAXMEM; i++){
						/* 尋找結構體中聊天室名相同的發送信息 */
						if(strcmp(info_class[i].chatroom, info_class[n].chatroom) == 0){
							char chatroom[20];
							strcpy(chatroom, info_class[n].chatroom);
							chatroom[strlen(chatroom)-1] = '\0';

							ticks = time(NULL);
							strftime(mytime,sizeof(mytime),"[%H:%M:%S] [",localtime(&ticks));
							strcpy(buf, mytime);  				// 顯示時間
							strcat(buf, chatroom);				// 顯示羣聊名稱
							strcat(buf, "]\t");
							strcat(buf, info_class[n].name);	// 顯示用戶名
							buf[strlen(buf)-1] = '\0';
							strcat(buf, ":\t");
							strcat(buf, temp);					// 客戶端消息內容
							strcat(buf, "\n");
							write(connfd[i], buf, strlen(buf));		/* 將消息發送給聊天室內的每一個人 */
						}
					}
				}
            }
            /* 如果發現關鍵字符串"send to",轉入私聊程序段 */
            else if((str = strstr(temp, "send to ")) != 0){
				int x;							/* 查找send to後跟用戶名的開始下標值 */
				char des[10];					/* 用來存儲目標用戶的名稱,從send to user中獲取 */
				x = strspn(temp, "send to ");	/* send to 後面用戶名字符串開始的索引 */
				strncpy(des, temp + x, strlen(temp)-x+1);
				strcat(des, "\n");
				for(i=0; i<MAXMEM; i++){
					if(strcmp(des, info_class[i].name) == 0){	/* 遍歷匹配user1的姓名 */
						while(1){
							if((len=read(connfd[n], temp, BUFFSIZE)) > 0){
								temp[len-1] = '\0';
								if(strcmp(temp, "back") == 0){	/* 如果收到back字段,則返回大廳 */
									write(connfd[n], "You are in the hall now, send to everyone or 'back' to hall.\n",
											strlen("You are in the hall now, send to everyone or 'back' to hall.\n"));
									break;
								}
								else{
									ticks = time(NULL);
									strftime(mytime,sizeof(mytime),"[%H:%M:%S]",localtime(&ticks));
									strcpy(buf, mytime);  				// 顯示時間
									strcat(buf, "\t");
									strcat(buf, info_class[n].name);	// 顯示用戶名
									buf[strlen(buf)-1] = '\0';
									strcat(buf, ":\t");
									strcat(buf, temp);					// 客戶端消息內容
									strcat(buf, "\n");
									write(connfd[i], buf, strlen(buf));
									write(connfd[n], buf, strlen(buf));
								}
							}
						}
					}
				}
            }
            /* 默認狀態下在大廳消息將發送給所有在線用戶 */
            else{
				ticks = time(NULL);
				strftime(mytime,sizeof(mytime),"[%H:%M:%S]",localtime(&ticks));
				strcpy(buf, mytime);  				// 顯示時間
				strcat(buf, "\t");
				strcat(buf, info_class[n].name);	// 顯示用戶名
				buf[strlen(buf)-1] = '\0';
				strcat(buf, ":[Global message]\t");
				strcat(buf, temp);					// 客戶端消息內容
				strcat(buf, "\n");

				/* 發給在線所有用戶 */
				for(i=0; i<MAXMEM; i++)
				{
					if(connfd[i] != -1)
						write(connfd[i], buf, strlen(buf));
				}
            }
        }
    }

}

/* 註冊函數 */
void regist(int n){
	char buf[BUFFSIZE],temp[50],info[20];
	int len,i;

	strcpy(buf,"Enter User name:");
	write(connfd[n],buf,strlen(buf));
	if((len = read(connfd[n], info, 20)) > 0)  /* 讀註冊時從客戶端傳回來的用戶名 */
	{
		fp = fopen("UserInfo.txt","a+");
		// strcpy(temp, info);
		while(!feof(fp)){						/* 一直讀到文件結束 */
			fgets(temp,50,fp);					/* 讀取一行 */
			if(strcmp(temp, info) == 0){			/* 如果存在某一行的值與輸入用戶名相同,則提示已註冊 */
				strcpy(buf,"User exist! Please select another name!\n");
				write(connfd[n], buf, strlen(buf));
				regist(n);						/* 如果用戶已存在就跳轉到函數開始重新註冊 */
			}
		}
		strcpy(buf,"Enter User password:");
		write(connfd[n], buf, strlen(buf));
		if((len = read(connfd[n], temp, 50)) > 0)  /* 讀註冊時從客戶端傳回來的密碼 */
		{
			strcat(info, temp);
			if(fp = fopen("UserInfo.txt","a+"))			/* 以追加方式打開用戶信息文件,第一次不存在會創建 */
			{
				fputs(info, fp);
				fclose(fp);								/* 寫入後關閉文件內容才能顯示 */
			}
		}
	}
	strcpy(buf,"Success, Go to login\n");
	write(connfd[n],buf,strlen(buf));

	login(n);			/* 註冊成功後跳轉到登錄 */
}

/* 登錄函數 */
void login(int n){
	char buf[BUFFSIZE],temp[50],info[50];
	int len;

	strcpy(buf,"User name:");
	write(connfd[n], buf, strlen(buf));
	if((len = read(connfd[n], temp, 50)) > 0){
		//temp[len-1] = '\0';
		fp = fopen("UserInfo.txt","r");
		while(!feof(fp)){						/* 一直讀到文件結束 */
			fgets(info, 50, fp);				/* 讀取一行 */
			if(strcmp(temp, info) == 0){		/* 如果存在某一行的值與輸入用戶名相同,則用戶已經註冊,可以正常登錄*/
				char str[50];
				/* 如果賬戶存在,那麼下一行就是本賬戶的密碼 */
				fgets(str, 50, fp);				/* 再讀一行,將密碼讀取出來 */
				strcat(info, str);
				fclose(fp);
				break;
			}
		}
		strcpy(buf,"Enter User password:");
		write(connfd[n],buf,strlen(buf));
		char str[50];
		if((len = read(connfd[n], str, 50)) > 0)  /* 讀註冊時從客戶端傳回來的密碼 */
		{
			//temp[len-1] = '\0';
			strcpy(info_class[n].name, temp);		/* 將客戶名賦給結構體name */
			strcat(temp, str);
			if(strcmp(temp, info) == 0){
				info_class[n].socket_name = connfd[n];	/* 登陸成功後將客戶套接字賦給結構體的套接字成員變量 */
				strcpy(buf,"Login success.\n");
				write(connfd[n],buf,strlen(buf));
			}
			else{
				strcpy(buf,"User not exist or Password error! Enter again.\n");
				write(connfd[n],buf,strlen(buf));
				login(n);
			}
		}
	}
}

/* 服務端接收處理大廳相應客戶端命令 */
void show(int n){
	char buf[BUFFSIZE], temp[5], info[50];
	int len;

	if((len = read(connfd[n], temp, 5)) > 0){
		temp[len-1] = '\0';     						/* 去除換行符 */

		if(strcmp(temp, "1") == 0){						/* 顯示在線用戶 */
			strcpy(info, "---Current online users---\n");
			for(int i=0; i<MAXMEM; i++)
			{
				if(connfd[i] != -1){
					strcat(info, info_class[i].name);	/* 將在線用戶名添加到info */
				}
			}
			write(connfd[n], info, strlen(info));
			write(connfd[n], "Not sure what to do next, try 'help' command.\n",strlen("Not sure what to do next, try 'help' command.\n"));
		}
		else if(strcmp(temp, "2") == 0){				/* 顯示所有聊天室 */
			strcpy(info, "---Current chatrooms---\n");
			for(int i=0; i<MAXMEM; i++)
			{
				if(connfd[i] != -1){
					for(int j=0; j<i; j++){
						if(strcmp(info_class[i].chatroom, info_class[j].chatroom) == 0){/* 同一個聊天室的名稱只算作一次 */
							strcat(info, info_class[i].chatroom);/* 將正在使用的聊天室名附加到info */
						}
					}
				}
			}
			write(connfd[n], info, strlen(info));
			write(connfd[n], "Not sure what to do next, try 'help' command.\n",strlen("Not sure what to do next, try 'help' command.\n"));
		}
		else if(strcmp(temp, "3") == 0){				/* 創建聊天室 */
			create_chatroom(n);
		}
		else if(strcmp(temp, "4") == 0){				/* 加入聊天室 */
			join_chatroom(n);
		}
		else{
			strcpy(buf,"Invalid command, input again.\n");
			write(connfd[n], buf, strlen(buf));
			show(n);									/* 無效命令碼,重新輸入 */
		}
	}
}

/* 創建聊天室函數 */
void create_chatroom(int n){
	char buf[BUFFSIZE], temp[50], info[20];
	int len;

	strcpy(buf, "Give the chatroom a name:");
	write(connfd[n], buf, strlen(buf));
	if((len = read(connfd[n], info, 20)) > 0){		/* 接收聊天室名字 */
		fp = fopen("ChatInfo.txt", "a+");
		while(!feof(fp)){							/* 一直讀到文件結束 */
			fgets(temp,50,fp);						/* 讀取一行 */
			if(strcmp(temp, info) == 0){			/* 如果存在某一行的值與輸入用戶名相同,則提示聊天室已被創建 */
				strcpy(buf,"Same name chatroom exist! Please select another name!\n");
				write(connfd[n], buf, strlen(buf));
				create_chatroom(n);					/* 如果聊天室已存在就跳轉到函數開始重新創建 */
			}
		}
		strcpy(buf, "Set a password for the chatroom:");
		write(connfd[n], buf, strlen(buf));
		if((len = read(connfd[n], temp, 50)) > 0){	/* 接收聊天室密碼 */
			strcpy(info_class[n].chatroom, info);	/* 創建完成後自動加入聊天室 */
			strcat(info, temp);
			if(fp = fopen("ChatInfo.txt","a+"))		/* 將聊天室信息添加到文件中保存 */
			{
				fputs(info, fp);
				fclose(fp);							/* 寫入後關閉文件內容纔會最終保存 */
			}
		}
	}
	strcpy(buf, "Success, now you are in the chatroom.\n");
	write(connfd[n], buf, strlen(buf));
	write(connfd[n], "You can send message in the chatroom or 'back' to hall.\n",strlen("You can send message in the chatroom or 'back' to hall.\n"));
}

/* 加入聊天室函數 */
void join_chatroom(int n){
	char buf[BUFFSIZE], temp[50], info[20];
	int len;

	strcpy(buf, "Enter the name of chatroom you want to join:");
	write(connfd[n], buf, strlen(buf));
	if((len = read(connfd[n], temp, 50)) > 0){
		fp = fopen("ChatInfo.txt", "r");
		while(!feof(fp)){
			fgets(info, 20, fp);				/* 讀取一行 */
			if(strcmp(temp, info) == 0){		/* 如果存在某一行的值與輸入相同,則存在聊天室,可以正常加入 */
				char str[50];
				/* 如果聊天室存在,那麼下一行就是本聊天室的密碼 */
				fgets(str, 50, fp);				/* 再讀一行,將密碼讀取出來 */
				strcat(info, str);
				fclose(fp);
				break;
			}
		}
		strcpy(buf, "Enter the password before you join in:");
		write(connfd[n], buf, strlen(buf));
		char str[50];
		if((len = read(connfd[n], str, 50)) > 0)  	/* 讀創建時從客戶端傳回來的聊天室密碼 */
		{
			strcpy(info_class[n].chatroom, temp);		/* 將聊天室名賦給結構體chatroom成員變量 */
			strcat(temp, str);
			if(strcmp(temp, info) == 0){
				strcpy(buf, "Joined, now you can send a message in the chatroom.\n");
				write(connfd[n], buf, strlen(buf));
			}
			else{
				strcpy(buf, "Chatroom not exist or Password error! Enter again.\n");
				write(connfd[n],buf,strlen(buf));
				join_chatroom(n);
			}
		}
	}
}




下面爲client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>

#define BUFFSIZE 128
#define HOST_IP "127.0.0.1"
#define PORT 8000

int sockfd;

void snd();

int main()
{
    pthread_t thread;       /*pthread_t 線程,gcc編譯時需加上-lpthread*/
    struct sockaddr_in serv_addr;   // struct sockaddr_in
    char buf[BUFFSIZE];
    /*初始化服務端地址結構*/
    bzero(&serv_addr, sizeof(struct sockaddr_in));  // bzero 清零
    serv_addr.sin_family = AF_INET;         // sin_family   AF_INET
    serv_addr.sin_port = htons(PORT);       // sin_port     htons(PORT)
    inet_pton(HOST_IP, &serv_addr.sin_addr);        // inet_pton
    // 創建客戶端套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);       // socket 創建套接字
    if(sockfd < 0)
    {
        perror("fail to socket");
        exit(-1);
    }
    // 與服務器建立連接
    printf("connecting... \n");
    if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) // connect
    {
        perror("fail to connect");
        exit(-2);
    }
    /* === 主進程接收數據,從此處開始 程序分做兩個線程 === */
    // 創建發送消息的線程,調用發送消息的函數snd
    pthread_create(&thread, NULL, (void *)(&snd), NULL);    // pthread_create
    // 接收消息的線程
    while(1)
    {
        int len;
        if((len=read(sockfd, buf, BUFFSIZE)) > 0)       // read 讀取通信套接字
        {
            buf[len] = '\0';        // 添加結束符,避免顯示緩衝區中殘留的內容
            printf("\n%s", buf);
            fflush(stdout);         // fflush 沖洗標準輸出,確保內容及時顯示
        }
    }
    return 0;
}

/*發送消息的函數*/
void snd()
{
    char temp[32], buf[BUFFSIZE];

    fgets(temp, 32, stdin); 		// fgets 會讀取輸入字符串後的換行符
    write(sockfd, temp, strlen(temp));      // write 寫入通信套接字
    while(1)
    {
        fgets(buf, BUFFSIZE, stdin);
        write(sockfd, buf, strlen(buf));
        /* 客戶端輸入bye則退出 */
        if(strcmp(buf, "bye\n") == 0)   // 注意此處的\n
            exit(0);
    }
}

命令行編譯時使用如下命令:

gcc -o server server.c -lpthread
gcc -o client client.c -lpthread

運行結果我就不放圖了,大家也可以跟我交流一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章