Linux平臺基於C編寫的文本通信平臺

代碼如下:

#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include<stdio.h>
#include<string.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include   <curses.h>

#define MAX_SIZE 1024

//用於發起連接
int ConnetServer(char *strName,int port)
{
	if(strName == NULL || port <= 0 || port > 65535)
		return -1;

	struct hostent *phost;
	phost = gethostbyname(strName);
	if (phost == NULL)
		return -1;
	
	struct sockaddr_in	sockaddr;
	int	client;  
	client = socket(PF_INET, SOCK_STREAM, 0);
	if (client < 0)
		return -1;

	memset(&sockaddr, 0, sizeof(struct sockaddr_in));
	sockaddr.sin_family = AF_INET;
	sockaddr.sin_port = htons(port);
	sockaddr.sin_addr.s_addr = *((long *) phost->h_addr);
//	int TimeOut = 2000;
//	setsockopt(client,SOL_SOCKET,SO_RCVTIMEO,(char*)&TimeOut,sizeof(TimeOut));

	if (connect(client, (struct sockaddr *) &sockaddr, sizeof(struct sockaddr_in)) < 0) 
	{
		close(client);
		return -1;
	}  
	return client;
}
// 用於接收數據
int RecvMessage(int client, char *buf, int size)
{
	int n = recv(client, buf, size, 0);
	if(n < 0)
		return -1;
	buf[n] = '\0';
	return n;
}
// 用於發送數據
int SendMsg(int s,char *buf,int len)
{
	int n = send(s,buf,len,0);
	if(n < 0)
		return -1;
	return n ;
} 
// 用於清空資源
void CleanUp(int s)
{
	close(s);
}

// 用於輸入命令
int GetInput(char *buf, int size)
{
	int count = 0;
	char c;
	while(count < size)
	{
		c = getchar();		
		if(c == '\n')
			break;
		buf[count++] = c;
	}
	buf[count++] = '\0';
	return count;
}
// 用於輸入文本
int GetContent(char *buf, int size)
{
	int count = 0;
	char c;
	while(count < size)
	{
		c = getchar();
		buf[count++] = c;
		if(c == '\n' && buf[count-2] == '\n')
			break;	
	}
	buf[count-1] = '\0';
	//printf("%s\n",buf);
	return count;
}
// 用於接受服務器端響應信息
int RecvResponse(int s ,char *buf,int size,int type)
{
	int len = 0;
	if ((len = RecvMessage(s, buf, size)) < 1)
	{
		printf("\nError....\n");
		return 0;
	}
	else
	{		
		//printf("%s\n",buf);
		if(type == 1)
		{
			if((buf[0] == 'S' || buf[0] == 's')
				&& buf[1] ==' ' 
				&& buf[2] == '1'
				&& buf[3] == '0'
				&& buf[4] == '5'){
				// 被信任
				return 2;
			}
			else 
				return -1;
		}		
	}
	return 1;
}

// 打印幫助
void PrintHelp()
{
   printf("--- HELP Content ---\n");
   printf("Command: q == QRY ---\n");
   printf("Command: r == GET---\n");
   printf("Command: s == SND---\n");
   printf("Command: b == BYE---\n");
   printf("Command: c == CHP---\n");
   printf("Command: h == HELP---\n\n");

}

// 用於解析迴響信息
int AnlysisResponse(char *buf)
{
	char dest[6];
	int index = 0;
	for(; index < 5; index++)
		dest[index] = buf[index];
	dest[index] = '\0';

	if(strcmp(dest,"S 101") == 0)
	{
		// MESSAGE QUEUE裏面MESSAGE的個數
		char *p = &buf[index+1];
		printf("====Message %d ====\n",atoi(p));
	}
	else if(strcmp(dest,"S 102") == 0)
	{
		// 獲得MESSAGE的內容
		//char *p = &buf[index+1];
		printf("%s\n",buf);	
		return 102;
	}
	else if(strcmp(dest,"S 103") == 0)
	{
		// 獲得MESSAGE的內容
		char *p = &buf[index+1];
		printf("%s\n",p);	
		return 103;
	}
	else if(strcmp(dest,"S 104") == 0)
	{
		// 獲得MESSAGE的內容
		printf("message saved!!!!\n");	
	}
	// 命令執行成功
	else if(buf[0] == 'S' || buf[0] == 's')
		printf("%s execute success!!!\n",dest);
	else if(strcmp(dest,"E 101") == 0)
		printf("E 101 need privatilty\n");
	else if(strcmp(dest,"E 103") == 0)
		printf("E 103 ====Message 0 ====\n");
	else if(strcmp(dest,"E 107") == 0)
		printf("E 107 server problem!!!!\n");
	else if(buf[0] == 'E' || buf[0] == 'e')
		printf("%s execute failed!!!\n",dest);
	else
		printf("Error: not understand command [%s]\n",buf);
	
	return 0;
}

// 用於執行QRY、GET、BYE等命令
void BaseCommand(int s,char *buf)
{	
	SendMsg(s,buf,strlen(buf));
	memset(buf,0,MAX_SIZE);
	if(RecvResponse(s,buf,MAX_SIZE,0)==0)
	{
		printf("Error:Recv response error!!!!\n");
		return ;
	}
	else if(AnlysisResponse(buf) == 102)
	{
		RecvMessage(s, buf, 2000);
		printf("%s",buf);
		RecvMessage(s, buf, 2000);
		printf("%s",buf);
	}
}
// 用於修改密碼
void ChpCommand(int s,char *buf)
{
	char password[20];
	strcpy(password,getpass("New Password:"));
	sprintf(buf,"CHP %s\r\n",password);
	//printf("%s\n",buf);
	SendMsg(s,buf,strlen(buf));
	memset(buf,0,MAX_SIZE);

	if(RecvResponse(s,buf,MAX_SIZE,0)==0)
	{
		printf("Error:Recv response error!!!!\n");
		return ;
	}
	AnlysisResponse(buf);

}
// 用於發送命令
void SendCommand(int s,char *buf)
{	
	char name[20];
	char message[2048];
	printf("Input Username:");
	GetInput(name,16);	
	sprintf(buf,"SND %s\r\n",name);
	SendMsg(s,buf,strlen(buf));
	memset(buf,0,MAX_SIZE);
	if(RecvResponse(s,buf,MAX_SIZE,0)==0)
	{
		printf("Error:Recv response error!!!!\n");
		return ;
	}
	else if(AnlysisResponse(buf) == 103)
	{
	//	printf("Input message:");
		memset(buf,0,MAX_SIZE);
		GetContent(message,2000);
		sprintf(buf,"%s\r\n.\r\n",message);
		if(SendMsg(s,buf,strlen(buf)) < 0)
			return ;
	//	printf("send:%s\n",buf);
		RecvResponse(s,buf,MAX_SIZE,0);
		AnlysisResponse(buf);
	}
}

// 主函數調度
void main(int argc, char **argv)
{
	char buf[MAX_SIZE];
	int len = 0;
	int s;
	char *hostname;//="";//	char *hostname="localhost";
	int port = 2962;
	char name[20];		
	char password[30];		
	
	hostname = argv[1];
	// 用於接受控制檯輸入,格式化成host、port
	if(argc < 2 || argc > 3)
	{
		printf("Error:host [ port ]\n");
		return ;
	}
	if(isdigit(argv[2][0])) {
		port = atoi(argv[2]);
	}
	else{
		printf("Error:The port is not a digit,now,use the default port[2962]!!!!!");
	}

	// 處理登錄的問題
	s = ConnetServer(hostname,port);
	if(s == -1){
		printf("\nCan't connect address.....\n");
		getchar();
		exit(0);
	}
	else{
		printf("\nConnects to server.\n");
		// 接受服務器端針對connect的響應信息
		// 注意,若協議在連接成功時,服務器端不返回信息,請註釋掉下面的語句
		RecvResponse(s,buf,MAX_SIZE,0);
	}

	// 循環的方式,完成首次密碼登錄
	while(1)
	{		
		printf("username:");
		GetInput(name,16);	
		strcpy(password,getpass("Password:"));
		sprintf(buf,"IAM %s %s\r\n",name,password);
		SendMsg(s,buf,strlen(buf));
		len = RecvResponse(s,buf,MAX_SIZE,1);
		if(len == 2)
		{
			printf("user:[%s] login success!!!\n",name);
			break;
		}
		else if(len == -1)
			printf("\nusername or password is error,please retype!!!!\n");
		else
		{
			printf("Error: login error and ready to quit!!!!");
			return ;
		}
	}

	// 用於獲得當前是否有消息
	strcpy(buf,"QRY\r\n");
	BaseCommand(s,buf);

	printf("Welcome to use text chat!!!!\n");
	PrintHelp();
	// 用戶主調度程序
	while(1)
	{				
		printf("input your command:>");
		GetInput(buf, MAX_SIZE);
		if(strcmp(buf,"q") == 0)
		{
			strcpy(buf,"QRY\r\n");
			BaseCommand(s,buf);
		}
		else if(strcmp(buf,"r") == 0)
		{
			strcpy(buf,"GET\r\n");
			BaseCommand(s,buf);
		}
		else if(strcmp(buf,"b") == 0)
		{
			strcpy(buf,"BYE\r\n");
			BaseCommand(s,buf);
			break;
		}
		else if(strcmp(buf,"s") == 0)
		{
			strcpy(buf,"SND");
			SendCommand(s,buf);
		}
		else if(strcmp(buf,"c") == 0)
		{
			strcpy(buf,"CHP");
			ChpCommand(s,buf);
		}
		else if(strcmp(buf,"h") == 0)
			PrintHelp();
		else 
			printf("Error:Your command is not understand!!!!\n");
	}	

	// 用於結束連接
	printf("\nDisconnects.\n");
	CleanUp(s);
	exit(0);
}



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