2007년 04월 29일
wipi c, clet의 네트워크 통신
wipi-c... 그니깐 clet은
우리가 익히 배웠던 C언어와는 다른 방식으로 작동합니다.
저두 잘 몰라서 고생한 부분입니다. --;;
이노에이스 쪽에서도 대충대충 설명해놨거든요.
(그나마 KTF의 지어는 낫습니다만,
결국 테스트 해보면서 알아보는 방법밖에 없습니다. 아님, 이통사 권유대로 걍 자바로 짜던가요.
자바는 midp규격하고 거의 똑같어요.)
네트워크연결할때.... 일반적인 c 소켓 통신하구 비슷하면서도 좀 다른데..
여기에 대해 간단히 이야기 해보도록 하겠습니다.
폰을 서버로 쓸일은 없을테니, 클라이언트 소스를 봅시다.
M_Int32 ret = 0;
M_Int32 ip;
M_Int16 port;
M_Int32 sockFD;
ret = MC_netConnect((NETCONNECTCB)ConnectCB, NULL);
sockFD = MC_netSocket(MC_AF_INET, MC_SOCKET_STREAM);
ip = ConvertToINAddr(DESTIP);
port = MC_utilHtons(DESTPORT);
ret = MC_netSocketConnect(sockFD, ip, port, (NETSOCKCONNECTCB)SocketConnectCB, NULL);
ret = MC_netSocketWrite(sockFD, sendBuff, BUFFSIZE);
ret = MC_netSocketRead(sockFD, recvBuff, BUFFSIZE);
....
MC_netConnect는 네트워크 초기화 함수입니다. 걍 그러려니 하고, 네트워크 사용하기 전에 맨처음 사용해주면 됩니다.
MC_netSocket함수는 socket()함수랑 같습니다. 여기서 소켓을 생성하겠죠? TCP, UDP..
그리고.. MC_netSocketConnect()에서는 접속을 합니다..
PC에서의 connect()함수죠.
그리고, PC처럼.. Send()에 해당하는 MC_netSocketWrite로 쓰고..
recv()에 해당하는 MC_netSocketRead로 통신하는구나..
라구 보입니다만...
No shit! 이렇게 하면 안됩니다.
맨먼저..
MC_netConnect()부터 MC_netSocketRead()까지 모두 비동기 함수들입니다.
반환하지 않아도 다음 단계로 걍 넘어갑니다.
그럼, 쓰레드 하나 더 만들어서, select()같은걸로 확인하면 되겠구나.. 하겠는데,
clet은 단일 프로세스로 쓰레드나 프로세스를 생성할 수 없습니다.
그럼, 우짤까요..
네트워크 함수들의 완료값은
뒤에 CB라고 붙은 것들..
MC_netConnect()의 (NETCONNECTCB)ConnectCB나
MC_netSocketConnect()의 (NETSOCKCONNECTCB)SocketConnectCB
의 콜백함수로 돌아옵니다.
사용자가 콜백함수를 정의한다음 함수포인터로 넘겨주면
콜백함수는 함수 작동이 완료한 후 오류값으로 사용자가 지정한 콜백함수의 업무를 수행하고 끝납니다..
문제는..
아까도 이야기했드시, clet은 멀티 쓰레드가 안된다는 점입니다.
콜백함수는 사용자가 정의한 함수 완료되건 말건,
중간에 자기일을 하구 종료합니다.
고로,
while(1){
...
} 같은걸로 기다릴수도 없는 노릇이고..
메인함수가 종료된후 돌아오거나, 심지어는 메인함수 중간에 자기가 일을 수행하기도 합니다. !!
그럼 우쩌나..
그렇타면....
걍 콜백함수 안에 다음 단계를 넣어버리면 됩니다.
ret = MC_netConnect((NETCONNECTCB)ConnectCB, NULL);
에서 호출되는 함수포인터, ConnectCB를 정의하기를..
void* ConnectCB(M_Int32 error, void *param) {
MC_knlPrintk("ConnectCB call\n");
sockFD = MC_netSocket(MC_AF_INET, MC_SOCKET_STREAM);
ip = ConvertToINAddr(DESTIP);
port = MC_utilHtons(DESTPORT);
ret = MC_netSocketConnect(sockFD, ip, port, (NETSOCKCONNECTCB)SocketConnectCB, NULL);
}
MC_netSocketConnect()에 들어가는 함수 포인터 SocketConnectCB를...
void* SocketConnectCB(M_Int32 fd, M_Int32 error, void *param) {
MC_knlPrintk("SocketConnectCB call\n");
if (error == 0) {
bSockConnected = TRUE;
MC_knlPrintk("netSocketConnect success!\n");
}
else if (error == M_E_ERROR) {
Close();
MC_knlPrintk("netSocketConnect failure!\n");
bSockConnected = FALSE;
}
return (void*)error;
}
// 라인길이상 일부 에러처리 소스는 일부러 뺏습니다. (주의요)
이렇게 일종의 콜백 체인을 만들어주면 됩니다.
위처럼 SocketConnectCB에서 bSocketConnect같은 전역변수 같은걸로 체크해서
bSocketConnect가 TRUE가 되면
이제 connect가 성공한 거니, MC_netSocketRead()로 통신해주시면 됩니다.
물론, 메인함수를 Timer 콜백함수에 넣어서 주기적으로 체크해주고 기다리게 해야겠죠?
특히 주의할 점중..
MC_netSocketRead()도 비동기 함수로
완료됬을때는 받은 문자열을 돌려주고,(모두 전송받았을때의 0까지 포함입니다.)
전송중일때는 M_E_WOULDBLOCK 오류를 돌려줍니다.
그럼, MC_netSocketRead()를 다시 받을때가지 다시 호출해주면 됩니다.
buffsize = BUFFSIZE;
while(1)
{
ret = MC_netSocketRead(sockFD, sendBuff, BUFFSIZE);
buffsize =buffsize-ret;
if(buffsize==0) break;
}
요렇게 하면 될것같죠?
물론 이렇게 하면 안됩니다.
MC_netSocketRead가 M_E_WOULDBLOCK를 돌려주면
무조건! 무조건!!
ret = MC_netSetReadCB(sockFD, SockReadCB, (void*)cmd);
를 넣어서, SockReadCB에서 MC_netSocketRead를 다시 호출해줘야합니다.
왜냐구요? 그건 저도 모릅니다..
임베디드니, 걍 그러려니 하셔야합니다. (이건 이노에이스쪽에서도 답변이 애매해요.. --;; 걍 규격이 그러려니 하세요)
buffsize = BUFFSIZE;
while(1)
{
ret = MC_netSocketRead(sockFD, sendBuff, BUFFSIZE);
if (ret == M_E_WOULDBLOCK) {
ret = MC_netSetReadCB(sockFD, SockReadCB, (void*)cmd);
}
buffsize =buffsize-ret;
if(buffsize==0) break;
}
위처럼 처리하고, SockReadCB에서는 더 받아야하는 buffsize를 넘겨주거나, 전역으로 받아서
다시 MC_netSocketRead를 호출해주고 완료 시키면 됩니다.
마찬가지 스위치를 하나 둬서 Timer에서 호출되는 메인함수에서 체크해주면 되구요.
지금까지 clet의 네트워크 방법을 알아봤습니다.
좀 이상한 방법인데, 자바 jlet는 뭐... 걍 쓰면 됩니다.
정규 자바 규격에서 별로 차이가 안나거든요.
clet은 이통사에서 쓰지 말라는 이유가 있습니다. (자기네들도 잘 모르거든요. --;;)
참,
KTF는 SKT과의 네트워크 방식은 차이가 좀 있습니다.
KTF는 빌컴헤더라고 통신할때 꼭 써야하는 헤더가 있습니다.
Billcom뭐라고 붙은 건데, 기존 네트워크 함수랑 큰 차이는 없습니다.
다만 그 함수를 쓰면 폰에서는 빌컴헤더가 자동으로 붙고, 서버에서는 그걸 처리해주는 부분이 있습니다.
(거기까지 쓰면 넘 길어지니, 그부분은 KTF 규격을 참조하세요. 아주 큰 차이가 있진 않습니다만..)
SKT는 그런게 없느니 걍 쓰면 됩니다.
마지막으로...
SKT는 http프로토콜도 사용할수 있지만, KTF는 사실상 불가능하다는것도 차이입니다.
똑같은 wipi래도 이래저래 차이가 많죠?
# by | 2007/04/29 16:23 | mobile programming | 트랙백 | 덧글(7)





☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
추가적으로 실재 폰상에서 테스트를 하려는데 WIPI Network API만으로 에뮬레이터환경이 아닌 폰상에서 돌아갈지 의문입니다. SKT 로 작업중인데, 에뮬레이터야 WIPI님께서 PC환경의 Network Interface와 악수 몇번하고.. (어익후 빠르구나..) 씽씽 돌아갑니다만.. SKT w240 모델에 올려보니 일반 소켓통신이 되질 않네요 ㅠ . 옛날 2.5G처럼 Wap 같은.. 별도의 Network Interface를 사용하는것일까요? 이거 이렇게되면 "협업하세용 ㄳ~" 라는 아주 슬픈 한마디를 듣게 될듯한 ㅠㅠ
네.. 저도 기분을 이해 합니다.
"협업하세용 ㄳ" 답변이 돌아오면.. 정말 ㅅㅂ스럽습니다.
사업적인 부분도 그렇지만 기술적인 부분도 빈익빈 부익부가 심한데..
컴X스나 넥X 모바일 같은 큰회사는 사내에 기술 노하우를 상당히 축적해서
공유하더군요.
특히 모바일 관련된 기술은 별것도 없으면서 기술 공유가 잘 안이루어지는데,
결론은.. 여기저기 발을 넓히는 방법말고는 없을것 같습니다. --;
저는 이젠 온라인 쪽에서 일해서 뭐라 도움 드리긴 어렵네요
정식 CP가 아니라서 정말 자료하나 구하기도 힘드네요. -_-;
다음 프로젝트부턴 JLet을 고려해 봐야 겠어요.