한 번에 소켓에서 보내고받을 수없는 이유를 지적 할 수 있습니까? 나의 이해에소켓 동시에 보내기/받기
당신이 보내려고하면
당겨 2 개 밀어 스트림 하나 하나가/당신이 (소켓 wasealready 오류가 발생하는 이유는 무엇 wasealready 오류
을 얻을 것이다 동시에받을 10035) 수신 측에서 보낸 확인 창과 관련이 있습니까? 마치 창문에 대해 열어 두는 것처럼?
한 번에 소켓에서 보내고받을 수없는 이유를 지적 할 수 있습니까? 나의 이해에소켓 동시에 보내기/받기
당신이 보내려고하면
당겨 2 개 밀어 스트림 하나 하나가/당신이 (소켓 wasealready 오류가 발생하는 이유는 무엇 wasealready 오류
을 얻을 것이다 동시에받을 10035) 수신 측에서 보낸 확인 창과 관련이 있습니까? 마치 창문에 대해 열어 두는 것처럼?
처음에는 오류 코드와 혼동스러워합니다. 다음은 관련성이있는 몇 가지 코드입니다.
connect()
을 시도합니다.한 번에 두 개의 차단 작업을 수행에서 당신을 방지하는 주요 요인은 WSAEINPROGRESS
오류합니다 - Winsock을 1.1 API의 제한은 당신이 한 번에 하나 개의 차단 작업을 수행 할 수 있습니다. 블로킹 호출을 시뮬레이트하기 위해 비 블로킹 오버랩 호출과 Winsock 2.0 API를 사용하여이 문제를 해결할 수 있습니다. 예를 들어 :
SOCKET sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
WSAEVENT hEvent = WSACreateEvent();
WSAEventSelect(sock, hEvent, FD_CONNECT); // register for connect notification
long iMode=1;
ioctlsocket(sock,FIONBIO,&iMode); // set non-blocking mode
WSAConnect(sock, address, sizeof(address), NULL, NULL, NULL, NULL);
WSAWaitForMultipleEvents(1, &events, FALSE, INFINITE, FALSE);
WSANETWORKEVENTS connect_result;
WSAEnumNetworkEvents(sock, hEvent, &connect_result);
if (connect_result.iErrorCode[FD_CONNECT] != 0) {
// connect failed, do something about it
}
WSACloseEvent(hEvent);
iMode = 0;
ioctlsocket(sock,FIONBIO,&iMode); // clear non-blocking mode; it won't play well with overlapped IO below
// Start an overlapped send
char *my_data = "Hello, world!";
WSAOVERLAPPED send_overlapped;
WSABUF send_buf;
send_buf.len = strlen(my_data);
send_buf.buf = my_data;
send_overlapped.hEvent = WSACreateEvent();
DWORD bytesSent;
WSASend(sock, &send_buf, 1, &bytesSent, 0, &send_overlapped, NULL);
if (WSAGetLastError() != WSA_IO_PENDING) {
// something went wrong, handle the error...
}
// Start an overlapped receive
char rdata[256];
WSAOVERLAPPED recv_overlapped;
WSABUF recv_buf;
recv_buf.len = sizeof(rdata);
recv_buf.buf = rdata;
recv_overlapped.hEvent = WSACreateEvent();
DWORD bytesRecvd;
WSARecv(sock, &recv_buf, 1, &bytesRecvd, NULL, &recv_overlapped, NULL);
if (WSAGetLastError() != WSA_IO_PENDING) {
// something went wrong, handle the error...
}
// Now wait for both to finish
WSAEVENT events[2];
events[0] = recv_buf.hEvent;
events[1] = send_buf.hEvent;
WSAWaitForMultipleEvents(2, events, TRUE, INFINITE, TRUE);
이 방법은 좀 더 복잡하지만, 매우 유연 - 당신이 겹친 I/O 작업을 해고하면, 바로 그 스레드가 같은 당신이 유지로 (다른 작업을 수행 할에 갈 수 있습니다 버퍼와 할당되지 않은 것). 주의해야 할 점은 GUI 스레드에서이 작업을 수행하면 메시지 루프를 변경해야한다는 것입니다. 겹쳐진 이벤트가 완료 되려면 스레드를 발행 한 스레드가 경고 대기를 수행해야합니다 (예 : MsgWaitForMultipleEvents
). . 위의 예에서는이 경고 대기를 수행하기 위해 WSAWaitForMultipleEvents
을 사용하고 있습니다. 또한, 중복 된 I/O 요청을 발행하는 스레드는 요청이 완료 될 때까지 종료되지 않아야합니다. 중복 된 I/O, 볼이 MSDN 페이지에 대한 일반적인 정보
: http://msdn.microsoft.com/en-us/library/ms686358(v=vs.85).aspx
10035이 WSAEWOULDBLOCK입니다, 당신은 블로킹 모드에서 소켓을 넣어 있나요? – nos