/**********************************************************************************
* 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;
}