티스토리 뷰
보통 TCP/IP만 써왔어서 이번에 UDP 관련코딩은 처음 해보는데,
bind()를 안하면 왜 수신이 안되는 지, 서버에서 sendto()를 먼저 하면 왜 수신이 안되는지 여기저기 찾아보다 알아낸 내용을 정리해본다.
[ UDP (User Datagram Protocol) 통신 ]
- 전송 계층의 비연결 지향적 프로토콜
- TCP/IP와 달리 연결 과정이 불필요함 (but, Connect 함수를 사용하는 경우도 존재)
- 1:1 뿐만 아니라 1:N, N:N 통신이 가능
- 흐름제어가 없어 패킷의 전송 순서나 수신 여부에 관한 오류를 확인할 수 없음
- 신뢰성보다 속도와 성능이 중요시 되는 경우(ex. 실시간서비스)에 사용함
UDP/IP 통신에서는 TCP/IP의 read(), write() 대신 recvfrom(), sendto() 함수를 이용해 자료를 송수신한다.
sendto() 함수는 전송할 목적지를 지정할 수 있고, recvfrom() 함수는 수신 데이터와 더불어 송신자의 정보도 얻을 수 있기 때문이다.
UDP/IP 통신은 TCP/IP 통신과 달리 클라이언트, 서버의 구분 없이도 데이터를 주고 받을 수 있다.
하지만 연결 과정이 불필요하다 해서 연결없이도 통신이 가능 한 것은 아니고, 수신 측에서 bind()를 통해 소켓에 주소와 포트를 연결시켜줘야 한다. 즉, recvform()을 먼저 호출하는 곳에는 반드시 bind() 함수를 사용해야 한다는 것!
* sendto()를 먼저 호출하는 경우는 bind를 해주지 않아도 된다.
이유는, sendto()를 호출 할 때 인자로 주어지는 상대방 주소정보를 참조하여 운영체제가 자동으로 bind를 해주기 때문!
혹시 돌아가는 예제가 필요한 사람은 첨부해 둔 Server/Client 코드를 참고 하시길...
단, 메세지 타입은 한글은 지원하지 않으니 적당히 수정해서 쓰길 바람!!
** UDP Server
** UDP Server Receive
SOCKET m_ServerSocket;
SOCKADDR_IN m_ServerInfo;
SOCKADDR_IN m_ClientInfo;
WSADATA wsa; // Winsock 데이터 구조체
int retVal = 0;
int nRecvLen = 0;
char Buffer[1024] = { 0, };
//WS2_32.DLL 초기화
if (WSAStartup(MAKEWORD(2, 2), &wsa) == SOCKET_ERROR)
{
WSACleanup(); return -1;
}
// UDP Socket 생성 (SOCK_DGRAM : UDP)
m_ServerSocket = socket(AF_INET, SOCK_DGRAM, 0);
m_ServerInfo.sin_family = AF_INET; // IPv4
m_ServerInfo.sin_addr.s_addr = htonl(INADDR_ANY); //Local
m_ServerInfo.sin_port = htons(12345);
retVal = bind(m_ServerSocket, (SOCKADDR*)&m_ServerInfo, sizeof(m_ServerInfo));
if (retVal == SOCKET_ERROR)
return -1;
int nClient_Size = sizeof(m_ClientInfo);
while (1)
{ // Recv 대기. Send한 Client 정보 저장
nRecvLen = recvfrom(m_ServerSocket, reinterpret_cast<char*>(Buffer),
1024, 0, (SOCKADDR*)&m_ClientInfo, &nClient_Size);
if (nRecvLen > 0)
{
// RECV 성공 시 MSG 처리..
}
}
closesocket(m_ServerSocket);
WSACleanup();
** UDP Server Send
int sendSize = sendto(m_ServerSocket, reinterpret_cast<char*>(Buffer),
nSize, 0, (struct sockaddr*)&m_ClientInfo, sizeof(m_ClientInfo));
if (sendSize < 0)
// Send 실패 시 알림 처리
** UDP Cilent
** UDP Client Receive
BYTE Buffer[884] = { 0,};
SOCKET m_clientSock;
SOCKADDR_IN m_ClientAddr;
int nSize = sizeof(m_ClientAddr);
int sendSize = 0;
while (1)
{
Recv_Size = recvfrom(m_clientSock, reinterpret_cast<char*>(Buffer),
1024, 0, (struct sockaddr*) &m_ClientAddr, &nSize);
if (Recv_Size >= 0)
{
// RECV 성공 시 MSG 처리..
}
}
closesocket(m_clientSock); //소켓 닫기
** UDP Client Send
WSADATA wsdata;
WSAStartup(MAKEWORD(2, 2), &wsdata);
m_clientSock = socket(AF_INET, SOCK_DGRAM, 0);
ZeroMemory(&m_ClientAddr, sizeof(m_ClientAddr));
m_ClientAddr.sin_family = AF_INET;
m_ClientAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
m_ClientAddr.sin_port = htons(12345);
int retval = sendto(m_clientSock, reinterpret_cast<char*>(Buffer),
0 nLen, 0, (SOCKADDR*)&m_ClientAddr, sizeof(m_ClientAddr));
if (retval < 0)
// 실패시 알림 처리
UDP Server/Client 예제 코드
'데이터 통신' 카테고리의 다른 글
Stateful / Stateless Protocol (0) | 2017.08.29 |
---|
- Total
- Today
- Yesterday
- 종로브리달메이
- 부평맛집
- 부평
- 광명무역센터컨벤션
- 그래픽카드후기
- 광명무역센터컨벤션 dvd
- 라레토추천인
- 브리달메이다이아
- 가성비맞춤정장
- 본식예복
- 종로다이아반지추천
- 냉면
- 라레토페이백
- C++
- 백준알고리즘
- 브리달메이
- 롯데리아
- 가산디지털단지 맛집
- 광명 무역센터 블랑논
- MFC
- 종로프로포즈링추천
- 본식맞춤예복
- 무한리필
- Visual Studio
- 광명무역센터컨벤션 #본식스냅 #메인스냅 #서브스냅 #촬영후기 #1인작가 #대표작가 #하루그라피
- 종로결혼반지추천
- 광명 본식 dvd
- 브리달메이웨딩밴드
- 가성비예복
- 브리달메이결혼반지
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |