ÃÑ ÆäÀÌÁö ¼ö : 3224
![]()
|
Facebook Joinc ±×·ì
Joinc QA »çÀÌÆ®
![]()
Tweet
joinc´Â Firefox¿Í chrome¿¡¼ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù. 1 ÀÔÃâ·Â ´ÙÁßÈ ¸ðµ¨1.1 BSD select ÀÔÃâ·Â ´ÙÁßÈ
ÀÔÃâ·Â ´ÙÁßÈ ±â¼úÀº À¯´Ð½º ¿î¿µÃ¼Á¦ ½Ã½ºÅÛ¿¡¼ Çϳª ÀÌ»óÀÇ ÆÄÀÏ·Î ºÎÅÍÀÇ ÀԷ°ú Ãâ·ÂÀ» ÇÔ²² °ü¸®Çϱâ À§Çؼ »ç¿ëÇÑ´Ù. ÀÚ¼¼ÇÑ ³»¿ëÀº ÀÔÃâ·Â ´ÙÁßȸ¦ Âü°íÇÑ´Ù.
À©µµ´Â BSD socketÀÇ ÀÔÃâ·Â ´ÙÁßÈ ÀÎÅÍÆäÀ̽ºÀÎ selectÇÔ¼ö¸¦ ±×´ë·Î »ç¿ëÇϰí ÀÖ´Ù. int select( __in int nfds, __inout fd_set *readfds, __inout fd_set *writefds, __inout fd_set *exceptfds, __in const struct timeval *timeout );¸î °¡Áö ´Ù¸¥ Á¡Àº nfds¸¦ »ç¿ëÇÏÁö ¾Ê´Â ´Ù´Â Á¡ÀÌ´Ù. À©¼Ó¿¡¼ nfds´Â BSD socket°úÀÇ È£È¯À» À§Çؼ ³²°ÜµÎ¾ú´Ù. ÀÌ´Â fd_set ±¸Á¶Ã¼ÀÇ Â÷ÀÌ¿¡ ±âÀÎÇÑ´Ù. BSD selectÀÇ fd_set°ú´Â ´Þ¸® À©¼ÓÀº fd_set¿¡ °ü¸®ÇÒ ÆÄÀÏÀÇ °³¼ö Á¤º¸¸¦ ÀúÀåÇϱ⠶§¹®ÀÌ´Ù. typedef struct fd_set {
u_int fd_count; // fd_array¿¡ ¼³Á¤µÈ ÆÄÀÏÀÇ ÃÑ °³¼ö
SOCKET fd_array[FD_SETSIZE];
} fd_set;
1.2 ÆÄÀÏ ´ëÀÀ
À©µµ´Â ¼ÒÄϰú ÆÄÀÏÀ» ´Ù¸¥ °´Ã¼·Î º¸±â ¶§¹®¿¡, selectÇÔ¼ö·Î ÆÄÀÏÀ» ´Ù·ê ¼ö´Â ¾ø´Ù. ¸®´ª½º´Â Ç¥ÁØÀԷ°ú ¼ÒÄÏÀ» ¸ðµÎ select·Î ó¸®ÇÒ ¼ö Àֱ⠶§¹®¿¡, ¿¹ÄÁµ¥ ÄÜ¼Ö Ã¤ÆÃ Ŭ¶óÀÌ¾ðÆ®µµ ´ÜÀÏ ¾²·¹µå ¸ðµ¨·Î ¸¸µé ¼ö ÀÖÁö¸¸, À©¼Ó select·Î´Â ±×·¸°Ô ÇÒ ¼ö ¾ø´Ù. ¾î¿ ¼ö ¾øÀÌ ¸ÖƼ ¾²·¹µå ÇÁ·Î±×·¡¹Ö ±â¼úÀ» ÀÀ¿ëÇØ¾ß ÇÑ´Ù. 1.3 Áö¿ø À©µµ ¹öÀü
windows 2000 Professional, windows 2000 Server À̻󿡼 Áö¿øÇÑ´Ù.
1.4 ¿¹Á¦#include <stdio.h> #include <winsock2.h> #define MAX_LINE 1024 #define BACKLOG 5 int main(int argc, char **argv) { WSADATA wsaData; SOCKET listen_fd, accept_fd, max_fd =0, sock_fd; struct sockaddr_in listen_addr, accept_addr; char buf[MAX_LINE]; int readn, addr_len; unsigned int i, fd_num=0; fd_set old_fds, new_fds; if(argc != 2) { printf("Usage : %s [PORT]\n", argv[1]); return 1; } if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0) return 1; listen_fd = socket(AF_INET, SOCK_STREAM, 0); if(listen_fd == INVALID_SOCKET) return 1; memset((void *)&listen_addr, 0x00, sizeof(listen_addr)); listen_addr.sin_family = AF_INET; listen_addr.sin_port = htons(atoi(argv[1])); listen_addr.sin_addr.s_addr = htonl(INADDR_ANY); if( bind (listen_fd, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) == SOCKET_ERROR) return 1; if(listen(listen_fd, BACKLOG) == SOCKET_ERROR) return 1; FD_ZERO(&new_fds); FD_SET(listen_fd, &new_fds); while(1) { int testi = 0; old_fds = new_fds; printf("accept wait %d\n", new_fds.fd_count); fd_num = select(0, &old_fds, NULL, NULL, NULL); if(FD_ISSET(listen_fd, &old_fds)) { addr_len = sizeof(struct sockaddr_in); accept_fd = accept(listen_fd, (struct sockaddr *)&accept_addr, &addr_len); if(accept_fd == INVALID_SOCKET) { continue; } FD_SET(accept_fd, &new_fds); } for(i = 1; i <= new_fds.fd_count; i++) { sock_fd = new_fds.fd_array[i]; if(FD_ISSET(sock_fd, &old_fds)) { memset(buf, 0x00, MAX_LINE); readn = recv(sock_fd, buf, MAX_LINE, 0); if(readn <= 0) { printf("socket close\n"); closesocket(sock_fd); FD_CLR(sock_fd, &new_fds); } else { send(sock_fd, buf, readn, 0); } if (--fd_num <=0 ) break; } } } closesocket(listen_fd); WSACleanup(); return 0; }
¸®´ª½º ÇÁ·Î±×·¥ º¸´Ù´Â ±¸Á¶°¡ ´Ü¼øÇÏ´Ù. ÀÌ´Â fd_set ±¸Á¶Ã¼ÀÇ Â÷ÀÌ¿¡ ±âÀÎÇÑ´Ù. ºñÆ® ¹è¿ÀÌ ¾Æ´Ñ ¼ÒÄÏ Áö½ÃÀÚ¸¦ ÀúÀåÇÏ´Â SOCK ¹è¿·Î, ¹è¿¿¡ ÀúÀåµÈ ¼ÒÄÏÀÇ Å©±â¸¦ ¾Ë·Á ÁÙ »Ó´õ·¯, ¹è¿À» (¸¶Ä¡ ¸µÅ©µå ¸®½ºÆ® ó·³)Á÷Á¢ °ü¸®ÇØ Áֱ⠶§¹®ÀÌ´Ù. ¸®´ª½º¶ó¸é ÇÁ·Î±×·¡¸Ó°¡ Á÷Á¢ ÇØ¾ß ÇÒ ÀÏÀ» À©¼Ó¿¡¼ ´ë½Å ó¸®ÇØ ÁØ´Ù. 2 WSAEventSelect ±¸Çö
À©µµÀÇ À̺¥Æ® °´Ã¼¸¦ ÀÌ¿ëÇØ¼ ³×Æ®¿öÅ© À̺¥Æ®¸¦ °¨ÁöÇÑ´Ù. °¢ ¼ÒÄÏ¿¡ ´ëÇØ¼ À̺¥Æ® °´Ã¼¸¦ ¼³Á¤Çϰí, ÀÌ À̺¥Æ® °´Ã¼¸¦ °üÂûÇÑ´Ù. À̺¥Æ®ÀÇ Å¸ÀÔÀÌ ´Ù¸¦ »Ó, À̺¥Æ®¸¦ ±â´Ù¸° ´Ù´Â Á¡¿¡¼ ±âº» ¿ø¸®´Â BSD select¸¦ ÀÌ¿ëÇÑ ¹æ½Ä°ú µ¿ÀÏÇÏ´Ù.
´ÙÀ½°ú °°Àº È帧À» °¡Áø´Ù.
WSAEventSelect ÇÔ¼ö·Î µî·ÏÇÒ ¼ö ÀÖ´Â ¼ÒÄÏ À̺¥Æ®´Â ´ÙÀ½°ú °°´Ù.
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 1024
#define PORTNUM 3600
struct SOCKETINFO
{
SOCKET fd;
char buf[MAXLINE];
int readn;
int writen;
};
WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];
int EventTotal=0;
struct SOCKETINFO *socketArray[WSA_MAXIMUM_WAIT_EVENTS];
int CreateSocketInfo(SOCKET s)
{
struct SOCKETINFO *sInfo;
if((EventArray[EventTotal] = WSACreateEvent()) == WSA_INVALID_EVENT)
{
printf("Event Failure\n");
return -1;
}
sInfo = (void *)malloc(sizeof(struct SOCKETINFO));
memset((void *)sInfo, 0x00, sizeof(struct SOCKETINFO));
sInfo->fd = s;
sInfo->readn = 0;
sInfo->writen = 0;
socketArray[EventTotal] = sInfo;
EventTotal ++;
return 1;
}
void freeSocketInfo(int eventIndex)
{
struct SOCKETINFO *si = socketArray[eventIndex];
int i;
closesocket(si->fd);
free((void *)si);
if(WSACloseEvent(EventArray[eventIndex]) == TRUE)
{
printf("Event Close OK\n");
}
else
{
printf("Event Close Failure\n");
}
for(i = eventIndex; i < EventTotal; i++)
{
EventArray[i] = EventArray[i+1];
socketArray[i] = socketArray[i+1];
}
EventTotal--;
}
int main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET sockfd, clientFd;
WSANETWORKEVENTS networkEvents;
char buf[MAXLINE];
int eventIndex;
int flags;
struct SOCKETINFO *socketInfo;
struct sockaddr_in sockaddr;
if(WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
{
printf("dll load error\n");
return 1;
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == INVALID_SOCKET)
{
return 1;
}
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(PORTNUM);
sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (CreateSocketInfo(sockfd)== -1)
{
return 1;
}
if(WSAEventSelect(sockfd, EventArray[EventTotal - 1], FD_ACCEPT|FD_CLOSE) == SOCKET_ERROR)
{
return 1;
}
if(bind(sockfd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
{
return 1;
}
listen(sockfd, 5);
while(1)
{
eventIndex = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE);
if(eventIndex == WSA_WAIT_FAILED)
{
printf("Event Wait Failed\n");
}
if(WSAEnumNetworkEvents(socketArray[eventIndex - WSA_WAIT_EVENT_0]->fd,
EventArray[eventIndex - WSA_WAIT_EVENT_0], &networkEvents) == SOCKET_ERROR)
{
printf("Event Type Error\n");
}
if(networkEvents.lNetworkEvents & FD_ACCEPT)
{
if(networkEvents.iErrorCode[FD_ACCEPT_BIT] != 0)
{
break;
}
if ((clientFd = accept(socketArray[eventIndex - WSA_WAIT_EVENT_0]->fd, NULL, NULL)) == INVALID_SOCKET)
{
break;
}
if(EventTotal > WSA_MAXIMUM_WAIT_EVENTS)
{
printf("Too many connections\n");
closesocket(clientFd);
}
CreateSocketInfo(clientFd);
if( (WSAEventSelect(clientFd, EventArray[EventTotal -1], FD_READ|FD_CLOSE) == SOCKET_ERROR) == SOCKET_ERROR)
{
return 1;
}
}
if(networkEvents.lNetworkEvents & FD_READ)
{
flags = 0;
memset(buf, 0x00, MAXLINE);
socketInfo = socketArray[eventIndex - WSA_WAIT_EVENT_0];
socketInfo->readn = recv(socketInfo->fd, socketInfo->buf, MAXLINE, 0);
send(socketInfo->fd, socketInfo->buf, socketInfo->readn, 0);
}
if(networkEvents.lNetworkEvents & FD_CLOSE)
{
printf("Socket Close\n");
freeSocketInfo(eventIndex-WSA_WAIT_EVENT_0);
}
}
}
WSAEventSelect ÇÔ¼ö¸¦ È£ÃâÇϸé ÀÚµ¿À¸·Î ¼ÒÄÏÀ» ºñµ¿±â/ºñºÀ¼â ¸ðµå·Î ¼³Á¤ÇÑ´Ù. ¶§¹®¿¡ À̸¦ °¨¾ÈÇØ¼ recv/recv ÇÔ¼ö¸¦ È£ÃâÇØ¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î FD_READ À̺¥Æ®¸¦ ¹Þ°í ³ª¼ readÀ» È£Ãâ ÇßÀ» ¶§, WSAEWOULDBLOCK¿¡·¯°¡ ¹ß»ýÇÒ ¼öµµ ÀÖ´Ù´Â Àǹ̴Ù. °ß°íÇÑ ¾ÖÇø®ÄÉÀ̼ÇÀ» ¸¸µé·Á¸é ÀÌ·¯ÇÑ ¿¹¿Ü »çÇ×À» ó¸®ÇØ ÁÖ¾î¾ß ÇÑ´Ù. À§ÀÇ ÇÁ·Î±×·¥Àº WSAEWOULDBLOCK 󸮴 Æ÷ÇÔÇÏÁö ¾Ê°í ÀÖ´Ù. 3 WSAAsyncSelect ±¸Çö
ºñµ¿±â À̺¥Æ® ¹æ½Ä Áß °¡Àå ³Î¸® »ç¿ëµÇ´Â ¹æ¹ýÁßÀÇ Çϳª´Ù. WSAEventSelect¿Í ºñ½ÁÇÑ ¸ÅÄ¿´ÏÁòÀ» °¡Áø´Ù. Â÷ÀÌÁ¡À̶ó¸é WSAEventSelect´Â À̺¥Æ® °´Ã¼¸¦ »ç¿ëÇØ¼ ÀÔÃâ·ÂÀ» ´Ù·ç°í, WSAAsyncSelectÇÔ¼ö´Â À©µµ¿ì ¸Þ½ÃÁö ÇüÅ·Π³×Æ®¿öÅ© À̺¥Æ®¸¦ ó¸®ÇÑ´Ù´Â Á¡ÀÌ´Ù.
WSAAsyncSelect¸¦ ÀÌ¿ëÇÑ µ¥ÀÌÅÍ Ã³¸® È帧ÀÌ´Ù. WSAEventSelect¿Í Å« Â÷À̰¡ ¾ø´Ù.
TCP ±â¹ÝÀÇ echo ¼¹ö ÇÁ·Î½ÃÁ® ÄÚµå. ³ªÁß¿¡ ½ÇÇà °¡´ÉÇÑ ¿¹Á¦¸¦ ¸¸µé¾îºÁ¾ßÁö
#include <windows.h> #include <winsock2.h> #define MAXLINE 1024 int main(int argc, char **argv) { HWND Windows = NULL; if(argc != 2) { printf("Usage : %s [port]\n", argv[0]); return 0; } WSAStartup(); listen_fd = socket(AF_INET,,,); Windows = CreateWindow(...); // µè±â ¼ÒÄÏÀÇ accept À̺¥Æ®¿Í close À̺¥Æ® ¸Þ½ÃÁö¸¦ // Windows Çڵ鷯°¡ °¡¸£Å°´Â À©µµÀÇ ÇÁ·Î½ÃÁ®°¡ ó¸®Çϵµ·Ï ÇÑ´Ù. WSAAsyncSelect(listen_fd, Windows, WM_SOCKET, FD_ACCEPT | FD_CLOSE); bind(); listen(); // °Á ·çÇÁµ¹¸é¼ ±â´Ù¸°´Ù. while(1) { Sleep(10000); } } // À©µµ ¸Þ½ÃÁö¸¦ ó¸®ÇÒ ÇÁ·Î½ÃÁ® ÄÚµå LRESULT CALLBACK WinProc(HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam) { SOCKET client_fd; // ¸Þ½ÃÁö ŸÀÔÀÌ ¼ÒÄÏ ¸Þ½ÃÁö¸é if(uMsg == WM_SOCKET) { switch(WSAGETSELECTEVENT(lParm)) { // accept À̺¥Æ®¶ó¸é case FD_ACCEPT: client_fd = accept(wParam,); WSAAsyncSelect(client_fd,,,); break; // read À̺¥Æ®¶ó¸é case FD_READ: recv(wParm,,,); send(wParm,,,); break; // ¼ÒÄÏ ´Ý±â À̺¥Æ®¶ó¸é case FD_CLOSE; closesocket(wParm); break; } } }
#include <windows.h> #include "resource.h" #define APP_PORT 0x1983 #define WM_SOCKETREAD (WM_APP + 100) SOCKADDR_IN saServer; SOCKET sock; BOOL CALLBACK DialogProc(HWND hDlg, UINT MSG, WPARAM wParam, LPARAM lParam) { switch(MSG) { case WM_INITDIALOG: { WSAAsyncSelect(sock, hDlg, WM_SOCKETREAD, FD_READ); }break; case WM_COMMAND: { switch(wParam) { case IDC_OK: case IDC_CANCEL: EndDialog(hDlg, 0); break; } }break; case WM_SOCKETREAD: { SOCKADDR from; char buffer[256]; int len = sizeof(SOCKADDR); memset(buffer, '\0', 256); recvfrom(sock, buffer, sizeof(buffer)-1, 0, &from, &len); SetDlgItemText(hDlg, IDC_MESSAGE, buffer); }break; } return(0); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { WSADATA data; if (WSAStartup(MAKEWORD(2,2), &data) != 0) return(0); int ret; sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (!sock) { WSACleanup(); return(0); } saServer.sin_family = AF_INET; saServer.sin_addr.s_addr = INADDR_ANY; saServer.sin_port = htons(APP_PORT); ret = bind(sock, (SOCKADDR *)&saServer, sizeof(SOCKADDR)); if (ret) { WSACleanup(); return(false); } DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc); closesocket(sock); WSACleanup(); return(1); }
![]() |
|
|||||||||||||||||||||||
|
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù. |
|