SOCKET 프로그램 머가 잘못 된것일까요..
서버와 클라인트 간에 통신을 하는 프로그램을 만드는데요..
1450바이트 이하를 한번에는 보내지고 왔다갔다 통신을 잘하는데요.
1500바이트는 왔다갔다 하지 못하네요..
이유가 먼지 해결좀 해주세요..ㅠ
[/code] Client
#define BUFSIZE 1455
short Client(int argc, char **argv)
{
WSADATA wsaData;
SOCKET hSocket;
char message[BUFSIZE];
char cancel[16];
char cancel1[16];
char message1[BUFSIZE],cDummyBuf[16];
int iLen =0,nResult, iLen1 =0;
SOCKADDR_IN dummyAddr;
int dummyLength,buff_len;
int addrLength;
SOCKADDR_IN servAddr;
if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){
ErrorHandling("WSAStartup() error!");
return RTN_TRUE;
}
hSocket=socket(PF_INET, SOCK_DGRAM, 0);
if(hSocket == INVALID_SOCKET){
ErrorHandling("socket() error");
return RTN_TRUE;
}
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family=AF_INET;
memset(cDummyBuf, CH_NULL,sizeof(cDummyBuf));
ScreenAllSet(" *TCP/IP접속IP* ",
CH_NULL,
CH_NULL,
" [.]SP = '.' ", TRUE);
nResult = InputStyleNum(2, 0, (uchar *)". ",
StrLen(15, (uchar*)cDummyBuf),
15, (uchar *)cDummyBuf, 30);
if(nResult < RTN_FALSE)
return RTN_TRUE;
servAddr.sin_addr.s_addr=inet_addr((const char*)cDummyBuf);
servAddr.sin_port=htons(atoi((char*)"9002"));
memset(cancel1,CH_NULL,sizeof(cancel1));
memset(cancel,CH_NULL,sizeof(cancel));
ScreenAllSet((char*)"Client Test", CH_NULL, CH_NULL, CH_NULL, 1);
while(1)
{
memset(message,CH_0,sizeof(message));
addrLength = sizeof(servAddr);
sendto(hSocket, message, strlen(message), 0, (SOCKADDR*)&servAddr, addrLength);
dummyLength = sizeof(dummyAddr);
buff_len = recvfrom(hSocket, message1, sizeof(message1), 0, (SOCKADDR*)&dummyAddr, &dummyLength);
message1[buff_len]=0;
if(memcmp(message, message1, sizeof(message1))){
sprintf(cancel,"Cancel = %d",iLen);
ScreenAllSet((char*)"Cancel", cancel, message, message1, 1);
Wait(500, WAIT_TIMER);
iLen++;
continue;
}
if(!message1) {
sprintf(cancel1,"NULL = %d",iLen1);
ScreenAllSet((char*)"NULL", CH_NULL, cancel, cancel1, 1);
Wait(500, WAIT_TIMER);
iLen1++;
continue;
}
if(KeyRead() == K_CANCEL){
ScreenAllSet((char*)"Result", CH_NULL, cancel, cancel1, 1);
WaitChar(0, WAIT_KEY | WAIT_TIMER, K_ENTER);
return RTN_CANCEL;
}
}
closesocket(hSocket);
WSACleanup();
return -1;
}
server int Server(int argc, char **argv) { WSADATA wsaData; SOCKET hServSock; char message[BUFSIZE]; int strLen; SOCKADDR_IN servAddr; SOCKADDR_IN clntAddr; int clntAddrSize; if(argc!=2){ ErrorHandling("Port error!"); } if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) ErrorHandling("WSAStartup() error!"); hServSock=socket(PF_INET, SOCK_DGRAM, 0); if(hServSock == INVALID_SOCKET) ErrorHandling("socket() error!"); memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family=AF_INET; servAddr.sin_addr.s_addr=htonl(INADDR_ANY); servAddr.sin_port=htons(atoi((char*)"9002")); if(bind(hServSock, (SOCKADDR*) &servAddr, sizeof(servAddr))==SOCKET_ERROR) ErrorHandling("bind() error"); ScreenAllSet((char*)"Server Test", CH_NULL, CH_NULL, CH_NULL, 1); while(1) { clntAddrSize=sizeof(clntAddr); strLen = recvfrom(hServSock, message, BUFSIZE, 0, (SOCKADDR*)&clntAddr, &clntAddrSize); message[strLen]=0; sendto(hServSock, message, strLen, 0, (SOCKADDR*)&clntAddr, sizeof(clntAddr)); } closesocket(hServSock); WSACleanup(); return -1; } void ErrorHandling(char *message) { ScreenAllSet((char*)"error", CH_NULL, message, CH_NULL, 1); exit(1); }
이건 TCP가 아닌거같은데요.
여러가지가 있지만. 우선 이건 UDP인거 같습니다. 이 구조는 서버/클라이언트 모두 tcp가 아닌 udp같구요, 두 컴퓨터를 wireless 환경에서 테스트 해보시면 아시겠지만, 플로우컨트롤 에러체킹 타임아웃등 tcp에서 지원하는 모든 기능들을 하나도 지원하지 않기 때문에 에러가 발생하는(에러가 아니라 데이터 로스 - 결과적으로는 파일이 깨진것처럼 보이겟죠) 것입니다.
자세한 UDP에 대한 정보는 http://www.joinc.co.kr/modules/moniwiki/wiki.php/article/UDP_%BC%D2%C4%CF_%C7%C1%B7%CE%B1%D7%B7%A1%B9%D6
에 가시면 보실수 있구요, 그냥 tcp로 쓰시려고 하시는 것이라면, 네이버 지식인에 가면 tcp 예제가 널려있으니까 참고하세요.
로그좀 보여주세요.
로그좀 보여주세요. 달랑 소스만 올려놓고 왜인지 모르겠어요 라고 학생같이 말씀하시면, 누가 도와주려고 하겠습니까?
1) 개발환경
2) wireshark로 캡쳐한 packet로그
적어도 요정도는 올려주셔야죠. 흠...
If A is success in life, then A equals x plus y plus z. Work is x; y is play; and z is keeping your mouth shut.
- Albert Einstein -
IP헤더의 DF비트도
IP헤더의 DF비트도 확인해보심이...
===== ===== ===== ===== =====
그럼 이만 총총...[竹]
http://elflord.egloos.com
===== ===== ===== ===== =====
그럼 이만 총총...[竹]
http://elflord.egloos.com
sendto()
client에서 sendto()의 return값을 확인해서
나머지 부분을 다시 sendto()하셨어야 합니다.
제가 알기로
제가 알기로 Broadcasting 소켓에서 sendto() 나 recvfrom으로 보냇을시에 얼마가 최종적으로 상대편 컴퓨터에 전달되었는지 알수 있는 방법은 보내는 컴퓨터와 받는 컴퓨터에서 ack넘버와 seq넘버를 헤더에 넣어 보내 타임아웃 체크를 해서 타임아웃이 되면 패킷을 드랍하고 다시 보내는 방법밖에 없는걸로 알고있습니다. sendto에서 return 하는 값은 보내는 컴퓨터의 입장에서 얼만큼을 broadcast햇는지를 return 하는 것이겟지만, 그것이 받는 컴퓨터의 입장에서 똑같이 받아진다는 보장은 없겟지요.. (TCP와는 틀리게..)
글쓴이 님께서는 제가 보기엔 TCP로 가시면 될꺼같은데, 지금 코드를보면 listen(), accept()부분이 서버에서 빠져있고, 클라이언트에선 connect() 부분이 빠져있는것 + 파라미터에 브로드케스팅으로 쓴거봐선 UDP 소켓을 생성하는 거 같네요.. TCP서버및클라이언트쪽에 예제는 널리되 널렸고, 딱히 보충할만한것들도 없는만큼 예제를 뒤져다 쓰시는게 젤 나은 방법이 아닌가싶네요.
제가 틀린부분이 있다면 꼭 지적 부탁드릴께요. 저도 배우는입장이라 완벽하진 않거든요.
TCP/UDP 문제는 아닌듯.
원글님의 글을 보면
UDP에서의 packet 손실문제는 아닌듯 합니다.
제가 보기엔
getsockopt()으로 SO_MAX_MSG_SIZE 옵션을 확인해 보시는 것이 좋을겁니다.
한번에 보낼 수 있는 size가 나올겁니다.
만약, 이 size보다 큰 것을 보낼려고 했다면,
EMSGSIZE이 return되겠죠.
댓글 달기