Linux C即时通信客户端(类似QQ)

原创
2013/05/04 12:43
阅读数 662
/**********************************************************************************
* Copyright (c) 2012, OpenSource All rights reserved.
*
* FileName   : 
* Description: 
*            
*
* Author     : 
* Date       : 
* Version    : 1.0
*
* Change Logs:
* 
***********************************************************************************/

/******************************************************************************
* Include files.
******************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>  // inet_pton

#pragma pack(push)  /* 保存默认的对齐方式 */
#pragma pack(1)    /* 设置当前对齐方式为n字节对齐 */

/******************************************************************************
* Macros.
******************************************************************************/
#define  SERVER_PORT 8888
#define MAX_BUF_SIZE  5100
#define  ID_LEN 128
#define  NAME_LEN 128
#define   MESSAGE_LEN 128
#define  SUCCESS 0
#define  FAILURE -1
#pragma pack(push)  /* 保存默认的对齐方式 */
#pragma pack(1)    /* 设置当前对齐方式为n字节对齐 */
int g_iSockFd;
typedef struct 
{

    char cUserStatus;
	char cUserName[10];
	char cUserAddr[32];
	struct ST_MANAGE_INFO *next;
}ST_MANAGE_INFO;
typedef struct
{
    char cMessageType; 
    char cUserName[10];
    char acId[10];              //user1  user2
    char acMessage[128];
    unsigned short  iUserNum;
    ST_MANAGE_INFO UserArray[10];    
    char acToUser[10];
}ST_LOGIN_INFO;

#pragma pack(pop)

int RecvData(int iSockFd);
void * SendThread();
int LoginEncode(char *pcBuf,char cMessageType,char * pcId,char *pcName,char *pcToUser,char *pcMessage);
int Decode(char *acBuf,char *cMessageType,char *cUserName,char *acId, char *cMessage,char *cUserNum,char *cUserStatus,char *cOnlineUserName,char *cOnlineUserAddr,char *acToUser);
/******************************************************************************
* functions.
******************************************************************************/
/******************************************************************************
* Function    : CommManageServerRecvThread
* Description :
*               
* Parameter   :
*               NO
* Return      : NO
* Explain     : NO
*******************************************************************************/
int main(int argc, char **argv)
{
	//int iServerSockFd;
	//int iClientSockFd;
	struct sockaddr_in stServerAddr;
	int iServerLen;
	pthread_t hThreadId;
	int iReturn;

	// create server socket
	g_iSockFd = socket(AF_INET, SOCK_DGRAM, 0);
	if (g_iSockFd < 0)
	{
		printf("socket create failed in CommManageServerRecvThread.\n");
		return FAILURE;
	}

	stServerAddr.sin_family = AF_INET;
	stServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	stServerAddr.sin_port = htons(SERVER_PORT);
	iServerLen = sizeof(stServerAddr);
    //bind
	iReturn = bind(g_iSockFd, (const struct sockaddr *)&stServerAddr, sizeof(stServerAddr));
	if(iReturn != SUCCESS)
	{
		printf("Bind failed.\n");
		close(g_iSockFd);
		return FAILURE;
	}
    //pthread creat
	pthread_create(&hThreadId, NULL, SendThread, NULL);

	iReturn = RecvData(g_iSockFd);
	if(iReturn != SUCCESS)
	{
		printf("read from server failed.\n");
		close(g_iSockFd);
		return FAILURE;
	}

	close(g_iSockFd);

	return SUCCESS;
}

/******************************************************************************
* Function    : CommManageServerRecvThread
* Description :
*               
* Parameter   :
*               NO
* Return      : NO
* Explain     : NO
*******************************************************************************/
int RecvData(int iSockFd)
{
	char acBuf[MAX_BUF_SIZE];
	int iReadNum;
	struct sockaddr_in stPeerAddr;
	int  iLen;
	char cMessageType;
        char cUserName[10];
        char acId[10];
	char acMessage[128];
        char cUserStatus;
        char acOnlineUserName[10];
        char acOnlineUserAddr[32];
        unsigned short  iUserNum;
        char acToUser[10];

	iLen = sizeof(stPeerAddr);

	while(1)
	{
		memset(acBuf, 0, sizeof(acBuf));

		iReadNum = recvfrom(iSockFd, acBuf, 0xFFFF, 0,(struct sockaddr *) &stPeerAddr,(socklen_t *) &iLen);
		if(iReadNum < 0)
		{
		    printf("read failed.\n");
		    return FAILURE;
		}

		//printf("%s:\n", inet_ntoa(stPeerAddr.sin_addr));
		//printf("%s\n", acBuf);

		Decode(acBuf,&cMessageType,cUserName,acId, acMessage,(char *)&iUserNum,&cUserStatus,acOnlineUserName,acOnlineUserAddr,acToUser);
		//printf("%c %s \n ",cMessageType,acMessage);
	}
    
	return SUCCESS;
}

/******************************************************************************
* Function    : CommManageServerRecvThread
* Description :
*               
* Parameter   :
*               NO
* Return      : NO
* Explain     : NO
*******************************************************************************/
void *  SendThread()
{
	//char acIp[128];
	char acText[4096];
	struct sockaddr_in stPeerAddr;
	int  iLen;
	int iReturn;

//	while(1)
//	{
	    //memset(acIp, 0, sizeof(acIp));
	    memset(acText, 0, sizeof(acText));

	    //scanf("%s %s", acIp, acText);
            // printf("The ip is %s\n", acIp);

	    stPeerAddr.sin_family = AF_INET;
	    inet_pton(AF_INET, "192.168.0.112", &stPeerAddr.sin_addr);
	    stPeerAddr.sin_port = htons(SERVER_PORT);

	    iLen = sizeof(stPeerAddr);
            LoginEncode(acText,'1',"10000","user5","user2","connect");
	    iReturn = sendto(g_iSockFd, acText, sizeof(ST_LOGIN_INFO), 0, (const struct sockaddr *)&stPeerAddr, iLen);
	    if(iReturn < 0)
	    {
	        printf("send failed.\n");
	    }

            while(1)
          {
            char cUser[10];
            char cMess[128];
            scanf("%s %s",cUser,cMess); 
            LoginEncode(acText,'4',"10000","user5",cUser,cMess);
           iReturn = sendto(g_iSockFd, acText, sizeof(ST_LOGIN_INFO), 0, (const struct sockaddr *)&stPeerAddr, iLen);
           if(iReturn < 0)
            {
                printf("send failed.\n");
            }
          }
//	} 

	return SUCCESS;
}


int LoginEncode(char *pcBuf,char cMessageType,char * pcId,char *pcUserName ,char *pcToUser,char*pcMessage)
{
    ST_LOGIN_INFO  *pstInfo;
 
    pstInfo = (ST_LOGIN_INFO *)pcBuf;
 
    strcpy(&(pstInfo->cMessageType), &cMessageType);
    strcpy(pstInfo->acId,pcId);
    strcpy(pstInfo->cUserName,pcUserName);
    strcpy(pstInfo->acToUser, pcToUser);
    strcpy(pstInfo->acMessage,pcMessage);
    return SUCCESS;
 }
int Decode(char *acBuf,char *cMessageType,char *cUserName,char *acId, char *cMessage,char *cUserNum,char *cUserStatus,char *cOnlineUserName,char *cOnlineUserAddr,char *pcToUser)
{
    int i;
    ST_LOGIN_INFO  *pstInfo;
    pstInfo = (ST_LOGIN_INFO *)acBuf;
    *cMessageType = pstInfo -> cMessageType;
    if(*cMessageType == '5')
    {
        strcpy(pcToUser,pstInfo->acToUser);
        strcpy(cMessage,pstInfo->acMessage);   
        printf("%s %s\n",pcToUser,cMessage);
    }
    if(*cMessageType == '3')
    {
        strcpy(cUserName,pstInfo ->cUserName);
        strcpy(acId,pstInfo -> acId );
        strcpy(cMessage,pstInfo -> acMessage );
        printf("%s",cMessage);
        *cUserNum=pstInfo ->iUserNum;
        for(i=0;i<(*cUserNum);i++)
        {
            *cUserStatus=((pstInfo->UserArray) + i)->cUserStatus;
             strcpy(cOnlineUserName,((pstInfo->UserArray) + i)->cUserName);
             printf("%c %s\n",*cUserStatus,cOnlineUserName);
        }
    }
    return SUCCESS;
}

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部