250 likes | 369 Views
16. INetMgr, ISocket API. INetMgr 인터페이스 INetMgr 인터페이스 함수는 장치의 네트워크 하위 시스템과 관련된 매개 변수를 가져오고 설정하는 메커니즘을 제공한다 . 이 함수를 사용하면 네트워크를 통해 데이터를 보내고 받는데 TCP 또는 UDP 를 사용하는 여러 개의 ISocket 인터페이스를 만들 수 있다 . ISocket 인터페이스
E N D
16. INetMgr, ISocket API • INetMgr 인터페이스 • INetMgr 인터페이스 함수는 장치의 네트워크 하위 시스템과 관련된 매개 변수를 가져오고 설정하는 메커니즘을 제공한다. • 이 함수를 사용하면 네트워크를 통해 데이터를 보내고 받는데 TCP 또는 UDP를 사용하는 여러 개의 ISocket 인터페이스를 만들 수 있다. • ISocket 인터페이스 • ISocket 인터페이스는 INETMGR_OpenSocket()을 사용하여 열린 TCP 및 UDP 소켓을 연결하고, 소켓을 통해 데이터를 전송하고 받으며, 닫는 방법을 제공한다. • 이 인터페이스에서 함수를 호출하려면 응용 프로그램에 Network 또는 All의 권한 수준이 있어야 한다. 16.1 INetMgr, ISocket 인터페이스를 이용하여 서버에 접속하기 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API • INETMGR_OpenSocket 함수 • 소켓을 만들고 ISocket 인터페이스에 대한 포인터를 반환합니다. 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API • ISOCKET_Connect 함수 • 유형이 AEE_SOCK_STREAM 소켓인 경우, 이 함수는 지정된 주소와 포트에 대한 TCP 연결을 초기화를 시도한다. • 인터넷 연결을 설정한 후에 호출된 콜백 함수에는 연결 작업이 완료된 방식을 설명하는 오류 코드가 전달된다. 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API • ISOCKET_Write 함수 • 단일 버퍼에서 연결된 소켓에 데이터를 기록한다. • 이 함수는 항상 기록한 바이트 수를 즉시 반환한다. • 기록한 바이트가 없고 연결은 계속 활성화되어 있으면 ISOCKET_Write() 함수는 AEE_NET_WOULDBLOCK을 반환한다. • 다시 호출할 시기에 대한 알림을 받으려면 호출자는 ISOCKET_Writeable()을 호출해야 한다. • ISOCKET_Read 함수 • 매개 변수로 지정된 단일 버퍼로 소켓에서 데이터를 읽어 온다. • 이 함수는 항상 결과를 즉시 반환한다. • 사용할 수 있는 데이터가 없고 연결이 계속 활성화되어 있으면 ISOCKET_Read()는 AEE_NET_WOULDBLOCK을 반환한다. • ISOCKET_Read()를 다시 호출할 시기에 대한 알림을 받으려면 호출자는 ISOCKET_Readable()을 호출해야 한다. 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API • ISocket_Writable() • 소켓에서 비블록킹 쓰기 작업을 처리해야 할 때 AEE에서 호출된 콜백 함수를 등록하는 함수 • 콜백 후 쓰기 함수가 반드시 처리되는 것은 아니므로 쓰기 함수에서 AEE_NET_WOULDBLOK를 반환할 경우 호출자는 항상 ISocket_Writable()을 다시 호출할 준비를 해야 한다. 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API • ISOCKET_Readable 함수 • 응용 프로그램은 지정된 소켓에서 비블록킹(non-blocking) 읽기 작업 (Accept, Read, ReadV 또는 RecvFrom)을 처리해야 할 때, 이 함수를 사용하여 AEE에서 호출된 콜백 함수를 등록할 수 있다. 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API • 16.2 INetMgr, ISocket API 예제 프로그램 • 클라이언트 (NetworkSample) • /*=============================================================================== • INCLUDES AND VARIABLE DEFINITIONS • =============================================================================== */ • #include "AEEModGen.h" // Module interface definitions • #include "AEEAppGen.h" // Applet interface definitions • #include "AEEShell.h" // Shell interface definitions • #include "AEEFile.h" // File interface definitions • #include "AEENet.h" // Socket interface definitions • #include "AEEStdLib.h" • #include "AEEMenu.h" • #include "AEEDisp.h" • #include "NetworkSample.bid" • #define MENU_EVT_CONNECT 401 • typedef enum • { • NET_NONE, • NET_GETHOST, • NET_CONNECT • } NetProcess; 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API typedef struct _CINetworkSample { AEEApplet a; // Mandatory first AEEApplet data member IMenuCtl* m_pIMenu; ISocket * m_pISocket; INetMgr * m_pINetMgr; AEECallback cbkLookup; INAddr addrsLookup[8]; int m_nLineHeight; AEEDeviceInfo m_dInfo; INPort wPort; INAddr dwAddr; NetProcess status; // uint16 APIFnType; // Storage for API function type selected // by user. } CINetworkSample; #define USAGE_HOST "203.250.33.57" #define USAGE_PORT 4444 // Server echo port // A few utility macros; #define ISDIGIT(c) ( (unsigned) ((c) - '0') < 10) #define ISALPHA(c) ( (unsigned) ( ((c)|32) - 'a') < 26 ) #define ISALNUM(c) ( ISDIGIT(c) || ISALPHA(c) ) #define min(a,b) ((a) < (b) ? (a) : (b)) #define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0])) IP 소켓 또는 종점의 IP 주소에 대한 네트워크 바이트 값을 나타낸다. typedef uint32 INAddr; 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API /*------------------------------------------------------------------- Function Prototypes -------------------------------------------------------------------*/ static boolean NetworkSample_HandleEvent(IApplet * pi, AEEEvent eCode, uint16 wParam, uint32 dwParam); static void DisplayMenu(CINetworkSample *pMe); static boolean NetworkSample_InitAppData(IApplet* pi); static void NetworkSample_FreeAppData(IApplet* pi); static void DisplayOutput(IApplet * pMe, int nline, char *pszStr, RGBVAL clrColor); void CommonConnectCB(void * pUser, int iError); void CommonReadCBFn (void *pUser); void CommonWriteCBFn(void *pUser); void DisconnectSocket(CINetworkSample * pMe); INAddr ConvertToINAddr(char *psz); void ConvertToIPAddr(INAddr inaddr, char *psz); int AEEClsCreateInstance(AEECLSID ClsId,IShell * pIShell,IModule * po,void ** ppObj) { *ppObj = NULL; if(ClsId == AEECLSID_NETWORKSAMPLE){ if(AEEApplet_New(sizeof(CINetworkSample), ClsId, pIShell,po,(IApplet**)ppObj, (AEEHANDLER)NetworkSample_HandleEvent,(PFNFREEAPPDATA)NetworkSample_FreeAppData) == TRUE) { // Add your code here ..... if (NetworkSample_InitAppData((IApplet*)*ppObj) == TRUE) return (AEE_SUCCESS); } } return (EFAILED); } 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API static boolean NetworkSample_HandleEvent(IApplet * pi, AEEEvent eCode, uint16 wParam, uint32 dwParam) { CINetworkSample * pMe = (CINetworkSample *)pi; switch (eCode) { case EVT_APP_START: { DisplayMenu(pMe); return(TRUE); } case EVT_KEY: if (pMe->m_pIMenu) { if ((IMENUCTL_IsActive(pMe->m_pIMenu) == FALSE) && (wParam == AVK_RIGHT)) { DisconnectSocket(pMe); IMENUCTL_SetActive(pMe->m_pIMenu, TRUE); IMENUCTL_Redraw(pMe->m_pIMenu); } return IMENUCTL_HandleEvent(pMe->m_pIMenu, EVT_KEY, wParam, 0); } else return FALSE; case EVT_APP_STOP: // Add your code here ..... return TRUE; 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API case EVT_COMMAND: { switch(wParam) { case MENU_EVT_CONNECT: { INetMgr * pINetMgr = NULL; ISocket * pISocket = NULL; int iRetVal; INAddr nodeINAddr; uint16 nPort; IDISPLAY_ClearScreen (pMe->a.m_pIDisplay); IMENUCTL_SetProperties(pMe->m_pIMenu, MP_NO_REDRAW); IMENUCTL_SetActive(pMe->m_pIMenu, FALSE); DisplayOutput((IApplet *)pMe, 1, "INetMgr, ISocket 이용하기", MAKE_RGB(0,0,0)); ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_NET, (void **)&pINetMgr); pISocket = INETMGR_OpenSocket (pINetMgr, AEE_SOCK_STREAM); pMe->m_pINetMgr = pINetMgr; pMe->m_pISocket = pISocket; nodeINAddr = ConvertToINAddr(USAGE_HOST); nPort = HTONS(USAGE_PORT); 호스트 바이트 순서와 네트워크 바이트 순서 간의 변환을 수행한다. 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API if((iRetVal = ISOCKET_Connect (pISocket, nodeINAddr, nPort, CommonConnectCB, (void *)pMe)) != AEE_NET_SUCCESS) { DisplayOutput((IApplet *)pMe, 7, "Network Error", MAKE_RGB(0xff, 0, 0)); } pMe->status = NET_CONNECT; return TRUE; } default: return TRUE; } } default: break; } return FALSE; } static void DisplayMenu(CINetworkSample *pMe) { AEERect rc; AECHAR szBuf[50]; AEEMenuColors mclr; if(ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_MENUCTL, (void **)&pMe->m_pIMenu) != SUCCESS) return; // Set display rectangle SETAEERECT (&rc, 0, 0, pMe->m_dInfo.cxScreen, pMe->m_dInfo.cyScreen); 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API // 선택된 메뉴의 색상을 설정한다. mclr.wMask = (MC_BACK | MC_TEXT | MC_SEL_BACK | MC_SEL_TEXT | MC_FRAME); mclr.cBack = RGB_WHITE; mclr.cText = RGB_BLACK; mclr.cSelBack = MAKE_RGB (146, 109, 255); mclr.cSelText = RGB_BLACK; mclr.cFrame = RGB_WHITE; IMENUCTL_SetColors (pMe->m_pIMenu, &mclr); // 메뉴 컨트롤의 타이틀을 생성한다 STREXPAND((byte *)"INegMgr, ISocket", STRLEN("INegMgr, ISocket"), szBuf, sizeof(szBuf)); IMENUCTL_SetTitle(pMe->m_pIMenu, NULL, 0, szBuf); IMENUCTL_SetRect(pMe->m_pIMenu, &rc); STREXPAND((byte *)"1. 서버에 연결하기", STRLEN("1. 서버에 연결하기"), szBuf, sizeof(szBuf)); IMENUCTL_AddItem(pMe->m_pIMenu, 0, 0, MENU_EVT_CONNECT, szBuf, 0); IMENUCTL_SetActive(pMe->m_pIMenu,TRUE); } static boolean NetworkSample_InitAppData(IApplet* pi) { CINetworkSample* pMe = (CINetworkSample*)pi; int pnAscent = 0; int pnDescent = 0; // Initialize the MenuCtl pointer to NULL pMe->m_pIMenu = NULL; pMe->m_pINetMgr = NULL; pMe->m_pISocket = NULL; pMe->status = NET_NONE; 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API pMe->m_nLineHeight = IDISPLAY_GetFontMetrics (pMe->a.m_pIDisplay, AEE_FONT_NORMAL, &pnAscent, &pnDescent); ISHELL_GetDeviceInfo(pMe->a.m_pIShell,&pMe->m_dInfo); return TRUE; } static void NetworkSample_FreeAppData(IApplet* pi) { CINetworkSample* pMe = (CINetworkSample*)pi; // 메뉴 컨트롤이 해지가 되지 않았다면 해지한다. if (pMe->m_pIMenu != NULL) { // 메뉴 컨트롤 해지하는 함수 IMENUCTL_Release (pMe->m_pIMenu); pMe->m_pIMenu = NULL; } if(pMe->status == NET_GETHOST) CALLBACK_Cancel(&pMe->cbkLookup); if (pMe->m_pISocket != NULL) { ISOCKET_Release (pMe->m_pISocket); pMe->m_pISocket = NULL; } if (pMe->m_pINetMgr != NULL) { INETMGR_SetLinger(pMe->m_pINetMgr,0); INETMGR_Release (pMe->m_pINetMgr); pMe->m_pINetMgr = NULL; } } 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API static void DisplayOutput(IApplet * pi, int nline, char *pszStr, RGBVAL clrColor) { AEEDeviceInfo di; // Device Info AECHAR szBuf[200] = {0}; // a buffer that supports 200 char string AECHAR * psz = NULL; int pixelWidth; AEEFont font = AEE_FONT_NORMAL; int pnFits = 0, dy; int totalCh = 0; int charHeight = 0; // Stores the char height in pixels for given font int pnAscent = 0; // Stores the ascent in number of pixels int pnDescent = 0; // Stores the descent in number of pixels AEERect rc; AEEApplet * pMe = (AEEApplet*)pi; if (pMe == NULL) return; // Get device information ISHELL_GetDeviceInfo(pMe->m_pIShell,&di); // Get the font metrics info charHeight = IDISPLAY_GetFontMetrics (pMe->m_pIDisplay, AEE_FONT_NORMAL, &pnAscent, &pnDescent); STREXPAND((byte *)pszStr, STRLEN(pszStr), szBuf, sizeof(szBuf)); if (nline < 0) { dy = di.cyScreen*2/5; } else{ dy = nline * charHeight; } 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API psz = szBuf; totalCh = STRLEN ((char *)pszStr); while ((totalCh > 0) && (*psz != NULL)) { pixelWidth = IDISPLAY_MeasureTextEx(pMe->m_pIDisplay, font, (AECHAR *) psz, // Start of the buffer to display, -1, di.cxScreen - 5, // maxWidth &pnFits); // Number of chars that will fit a line if (pnFits == 0) return; SETAEERECT(&rc, 0, dy, di.cxScreen, charHeight); IDISPLAY_EraseRect(pMe->m_pIDisplay, &rc); IDISPLAY_SetColor(pMe->m_pIDisplay,CLR_USER_TEXT,clrColor); IDISPLAY_DrawText(pMe->m_pIDisplay, AEE_FONT_NORMAL, psz, pnFits, 5 /*start dx*/, dy, 0 /* use default rectangle coordinates */, 0); psz += pnFits; // move pointer to the next segment to be displayed totalCh -= pnFits; // reduce the total number of characters to still display dy += charHeight; // Place next line charHeight pixels below the // previous line. IDISPLAY_Update(pMe->m_pIDisplay); if (totalCh < pnFits) pnFits = totalCh; // if total number is less than pnFits, adjust pnFits } return; } 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API INAddr ConvertToINAddr(char *psz) { INAddr ul = 0; int nByte = 0; char c; if(!psz) return 0; while (ISDIGIT(*psz)) { int n = 0; while ( ISDIGIT(c=*psz)) { n = n*10 + (c - '0'); ++psz; } ((char*)&ul)[nByte++] = n; if (nByte == 4 || *psz != '.') break; ++psz; } if (nByte < 4 || ISALNUM(*psz)) ul = 0xFFFFFFFF; // Invalid address return ul; } 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API void CommonConnectCB(void * pUser, int iError) { CINetworkSample * pMe = (CINetworkSample*)pUser; int32 iRetValue; char pszData[20] = "Brew 수업 중..."; char szBuf[20] = {0}; char *psz = NULL; int cbWrite; psz = pszData; cbWrite = STRLEN (pszData); DisplayOutput((IApplet *)pMe, 3, "소켓에 쓸 데이타", MAKE_RGB(0xff, 0, 0)); iRetValue = ISOCKET_Write(pMe->m_pISocket, (byte *)psz, (uint16)cbWrite); if(iRetValue == AEE_NET_WOULDBLOCK) { ISOCKET_Writeable(pMe->m_pISocket, CommonWriteCBFn, (void *)pMe); } else if(iRetValue == AEE_NET_ERROR) { DisplayOutput((IApplet *)pMe, 4, "AEE_NET_ERROR", MAKE_RGB(0xff, 0, 0)); DisconnectSocket(pMe); return; } else if(iRetValue > 0) { DisplayOutput((IApplet *)pMe, 4, (byte *)psz, MAKE_RGB(0xff, 0, 0)); } DisplayOutput((IApplet *)pMe, 6, "소켓에 읽은 데이타", MAKE_RGB(0xff, 0, 0)); iRetValue = ISOCKET_Read(pMe->m_pISocket, (byte *)szBuf, sizeof(szBuf)) ; 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API if(iRetValue == AEE_NET_WOULDBLOCK) { DisplayOutput((IApplet *)pMe, 7, "AEE_NET_WOULDBLOCK", MAKE_RGB(0xff, 0, 0)); ISOCKET_Readable(pMe->m_pISocket, CommonReadCBFn, (void*)pMe); } else if(iRetValue == AEE_NET_ERROR) { DisplayOutput((IApplet *)pMe, 7, "AEE_NET_ERROR", MAKE_RGB(0xff, 0, 0)); DisconnectSocket(pMe); } else if(iRetValue > 0) { DisplayOutput((IApplet *)pMe, 7, (byte *)szBuf, MAKE_RGB(0xff, 0, 0)); DisconnectSocket(pMe); } else if(iRetValue == 0) { DisplayOutput((IApplet *)pMe, 7, "읽은 데이터 값이 없다", MAKE_RGB(0xff, 0, 0)); DisconnectSocket(pMe); } } void CommonWriteCBFn(void *pUser) { CINetworkSample * pMe = (CINetworkSample*)pUser; int32 iRetValue; char pszData[20] = “Brew 수업 중…"; char *psz = NULL; int cbWrite; ISocket *pISocket = pMe->m_pISocket; psz = pszData; cbWrite = STRLEN (pszData); 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API iRetValue = ISOCKET_Write(pISocket, (byte *)psz, (uint16)cbWrite); if(iRetValue == AEE_NET_WOULDBLOCK) { ISOCKET_Writeable(pMe->m_pISocket, CommonWriteCBFn, (void *)pMe); } else if(iRetValue == AEE_NET_ERROR) { DisplayOutput((IApplet *)pMe, 4, "AEE_NET_ERROR", MAKE_RGB(0xff, 0, 0)); DisconnectSocket(pMe); } else if(iRetValue > 0) { DisplayOutput((IApplet *)pMe, 4, (byte *)psz, MAKE_RGB(0xff, 0, 0)); } } void CommonReadCBFn (void *pUser) { CINetworkSample * pMe = (CINetworkSample*)pUser; int32 iRetValue; char szBuf[100] = {0}; ISocket *piSock = pMe->m_pISocket; iRetValue = ISOCKET_Read(piSock, (byte *)szBuf, sizeof(szBuf)); if (iRetValue == AEE_NET_WOULDBLOCK) { ISOCKET_Readable(piSock, CommonReadCBFn, (void*)pMe); return; } 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API else if (iRetValue == AEE_NET_ERROR) { DisplayOutput ((IApplet *)pMe, 9, "Read Error!",MAKE_RGB(0, 0, 0xff)); DisconnectSocket (pMe); } else if (iRetValue > 0) // data has been read { // The data has been read from the socket. Display Data read. DisplayOutput ((IApplet *)pMe, 9, (byte *)szBuf, MAKE_RGB(0, 0, 0xff)); DisconnectSocket (pMe); } else // rv == 0 { DisplayOutput ((IApplet *)pMe, 9, "읽을 데이터가 없다.", MAKE_RGB(0, 0, 0xff)); DisconnectSocket (pMe); } } void DisconnectSocket(CINetworkSample * pMe) { if(pMe->status == NET_GETHOST) CALLBACK_Cancel(&pMe->cbkLookup); if (pMe->m_pISocket != NULL) { ISOCKET_Release (pMe->m_pISocket); pMe->m_pISocket = NULL; } if (pMe->m_pINetMgr != NULL) { INETMGR_SetLinger(pMe->m_pINetMgr,0); INETMGR_Release (pMe->m_pINetMgr); pMe->m_pINetMgr = NULL; } } 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API • 서버 프로그램 (ExampleServer.java) 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API • 16.3 실행 결과 • 클라이언트 결과 임베디드 모바일 프로그래밍
16. INetMgr, ISocket API • 서버 결과 임베디드 모바일 프로그래밍