[완료]WSAGetLastError()에 대해 질문드립니다.

richjaff의 이미지

IOCP 부분에서 입/출력이 끝날때마다 에러 검사를 하기 위해
WSAGetLastError()를 호출하는 부분이 필수적으로 붙게됩니다.
이 에러 검출용 코드의 경우 동기화가 필요한가요?

예를 들어서, A라는 워커쓰레드에서 발생한 에러를 멀쩡하게 IO를 잘 수행중인 B 워커쓰레드에서
A에서 일어난 에러를 받는 현상이 있을 수 있는지 궁금합니다.

두번째 궁금한점은, WSAGetLastError()코드의 경우, WSASend, WSARecv에만 반응하고
다른 네트워크 함수인 closesocket이나 accept와 같은 코드에는 반응을 안하는지 궁금합니다.

이 두가지 사항에 대해 조언 좀 부탁드립니다.

bugiii의 이미지

첫번째 경우는 다음과 같은 언급이 있습니다. WGLE는 한 쓰레드안의 모든 소켓용이고, getsockopt + SO_ERROR 은 소켓마다 지정되는 것입니다. IOCP의 워커들은 계속 변할 것이기 때문에 조금 혼동될 소지가 있어 보이는군요.

Quote:
The WSAGetLastError function returns the last error that occurred for the calling thread. When a particular Windows Sockets function indicates an error has occurred, this function should be called immediately to retrieve the extended error code for the failing function call. This extended error code can be different from the error code obtained from getsockopt when called with an optname parameter of SO_ERROR, which is socket-specific since WSAGetLastError is for all thread-specific sockets.

두번째는 문서의 리턴 값에 대한 설명을 보시면 됩니다.

p.s. 문서를 꼼꼼히...

richjaff의 이미지

두번째 문제는 해결했습니다.

하지만, 첫번째가 아직도 걸리네요.
자꾸 아래의 문제가 발생합니다.

=================== 어셉트 쓰레드 부분 =================================

어셉트 완료 시점부터

if( WSARecv(cPtr->sock, &(cPtr->iworkstream->wsabuf), 1, &recvbytes,&flags, &(cPtr->iworkstream->overlapped), NULL) == SOCKET_ERROR ){
if(WSAGetLastError() != WSA_IO_PENDING){
com.PushDataString("[IOCP]Client Recv Requirment Failed.");
chmap.SetDisconnect(cPtr->charPtr); // 캐릭터 맵부분 삭제
cPtr->status = OFFLINE; // 오프라인으로 셋팅
RequirCloseConn(cPtr); // 쓰기 작업 중일때는 오프라인 상태표시만 하고 스킵함. (이후에 전송 완료 작업이 통보되고 나서 IO핸들을 모두 삭제.
continue;
}
}

위에서 소켓에 대한 입출력이 실패하고 난뒤에 실패된 소켓에 대한 완료 통보가 올 수 있나요?
현재 몇십분에 한번꼴로 나타나는 에러의 상황을 말씀드리자면,

1.어셉트 부분이 성공하고 초기 리시브 요청을 실시한다.
2.WSAGetLastError로 확인을 실시한다.
3.초기 리시브 요청에서 실패한다고 떴으므로 종료과정을 실시한뒤 continue 시킨다.
4.워커쓰레드로 분명 위에서 실패했다고 뜬 IO요청에 대해 완료통보가 온다. << (문제의 상황)

지금 나타나는 것이 이런 경우입니다.

ps.방금 WSAGetLastError 관련해서 따로 소스를 코딩해서 테스트 해봤는데 역시나 좀 이해하기 힘든 결과가 나왔습니다.
테스트한 소스 전체를 다른 글에 새로 올리겠습니다.

============= 추가 수정 =====================================

제대로 테스트 해보니 WSAGetLastError는 확실히 쓰레드에 독립적이더군요.
뭐가 문제인지 좀더 꼼꼼히 확인해봐야할것 같습니다.
답변 주셔서 감사합니다.

richjaff의 이미지

어셉트 쓰레드에서 다음 구문이 실행되어지는 것보다 워커쓰레드의 완료통보의 반응이 훨씬 빠를때 생기는 문제더군요;
실제로 워커쓰레드 2개만으로 동접 180명까지 받아서 원활한 게임처리를 했을 정도니 IOCP의 성능이 참 대단한것 같습니다.
그리고 비동기IO 작업 실패시에는 완료통보로 뜨지않는것이 확실하더군요.
위에서 나타난 문제는 다음처럼 코딩했기 때문이었습니다.

============ 어셉트 쓰레드 =============================

어셉트 수행

최초 WSARecv 수행;

Synchronized
{
클라이언트 리스트에 추가
}

============= 워커 쓰레드 ==============================

완료 통보

Synchronized
{
클라이언트 리스트에 존재하는지 체크함.
}

======================================================

위에서 최초 읽기작업이 요청되고 난뒤였는데 워커쓰레드에서 먼저 더 빠르게 완료통보가 내려오고
임계구역에 진입하는 바람에, 없는 클라이언트 리스트로 떴었던 것인데,
동기화 블록 배치를 바꿔서 이문제는 해결했습니다.
조언 주셔서 정말 감사드립니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.