출처 : http://kukuta.tistory.com/27

 오늘은 소켓의 종료와 그에 따라 발생하는 소켓의 상태 변화에 대해 알아 보도록 하겠다.

 먼저 소켓은 생성될 때는 3-way hand shaking을 통해서 생성되지만, 종료 될때는 한단계 더 많은 4-way hand shaking을 거쳐 종료 된다.

four way handshake

four way handshake


  위에서 분명히 4-way.. 4단계라고 이야기 했다. 그럼 어떤 4단계를 거치는지 알아 보자.

  1. A가 B에게 연결 종료를 요청한다.
  2. B는 바로 종료를 하는 것이 아니라, 단순히 ACK만을 날리고 있다. B도 종료 하기 전에 할
     일이 있기 때문에 바로 FIN을 날리지 않고, 단순히 ACK를 날리고 CLOSE_WAIT 상태로 넘어
     간다.
 3. 볼일을 다 보고난 B는 이제서야 FIN을 날리고 연결을 종료 하고자 한다.
 4. A는 B의 FIN을 잘 받았다는ACK를 B에게 보내게 되고, A의 ACK를 받으면 B는 종료한다.

 4의 과정에서 A는 ACK를 날리고 난후 소켓이 제거될때 까지 TIME_WAIT상태에 있게 되며 이 시간은 대략 30 초 정도지만 시스템 마다 다르다.
 TIME_WAIT에 있는 동안에는 커널이 주소와 port를 바인딩 하고 있기때문에 재사용 할 수가 없다. 게다가 TIME_WAIT에 있는 주소와 port를 재사용 요청을 하면 TIME_WAIT 시간을 더욱 늘릴 뿐이다.
 
 그렇다면 이렇게 불편한 TIME_WAIT를 왜 사용해야만 하는가??
 만일 A가 B로 보낸 마지막 종료 메시지(SEQ:5001,ACK:6002) 이후 바로 종료 했다고 가정하자. 그런데 라우터의 문제라던지 기타등등의 네트워크 상에서 발생하는 어떠한 원인에 의해 마지막 종료 메시지가 B에 도착하지 않게되었다.
 이때쯤 되면 B는 종료하지 못하고(TCP는 소심해서 뭘 하던지 완료 메시지를 받아야 마음을 놓는다) 다시 A에게 한번 더 FIN(SEQ:6001, ACK:5001)을 날린다.
 여기서 A가 TIME_WAIT가 아니라 바로 종료 되어버린 상태 였다면, 이 마지막 FIN 역시 무시했을 테고 B는 여전히 A가 종료 되었는지 살아 있는지 모르고 아둥바둥거리고 있게 될 것이다. 하지만 TIME_WAIT에 있는 A의 소켓은 여전히 주소와 포트를 바인딩 하고 있는 상태이기 때문에 다시 날아 오는 B의 FIN을 감지하고 다시한번 마지막 ACK를 날려 줄 수 있는 것이다.

참 고 :
 열혈강의 TCP/IP 소켓 프로그래밍 : 윤성우
 Unix Network Programming : Stevens

관련 글 :  
 TIME_WAIT state vs SO_REUSEADDR option -> http://kukuta.tistory.com/17

'Programing > Network' 카테고리의 다른 글

소켓 종료와 TIME_WAIT(Socket termination and TIME_WAIT)  (1) 2011.05.17
Posted by 패스맨

댓글을 달아 주세요

  1. kukuta 2011.05.28 13:31 신고 Address Modify/Delete Reply

    참고로 http://kukuta.tistory.com/155 같이 보시면 더 도움이...
    암튼 들러 주셔서 감사합니다.

출처 http://kuaaan.tistory.com/99

Q1: 동일한 스레드에서 동일한 CriticalSection에 두번 진입하면 Block이 걸릴까?
A1: 아니다. 스레드가 이미 자신이 소유한 CriticalSection을 다시 소유하려고 시도하는 것은 전혀 문제될 것이 없다. CriticalSection 개체는 내부적으로 LockCount와 OwningThread라는 멤버가 있어서 자신이 몇번 Lock이 걸렸는지와 어느 스레드에 소유되었는지를 기억하고 있다. 
다른 스레드가 소유한 CriticalSection 개체에 대해 EnterCriticalSection을 시도하면 당연히 Block되겠지만, CriticalSection을 소유한 스레드가 다시 EnterCriticalSection을 시도하면 즉시 리턴되고, 내부적으로 LockCount가 하나 증가한다. 대신, EnterCriticalSection한 횟수만큼 LeaveCriticalSection을 호출해주어야 CriticalSection 개체가 Signaled 상태로 돌아온다. 두번 EnterCriticalSection한 후 한번만 LeaveCriticalSection하면? 당연히 한번 EnterCriticalSection했을 때의 상태와 동일해진다.

디버거에서 CriticalSection 개체를 들여다 보면 아래와 같은 멤버들로 구성된 것을 알 수 있다. LockCount의 초기값은 -1이고, 한번 소유되면 0으로 증가한다.

※ 참고로... linux의 posix mutex는 lock을 두번 걸 경우 데드락에 걸리는 문제가 있었다.


Q2: A라는 스레드가 소유한 CriticalSection을 B라는 제3의 스레드가 해제할 수 있나?
A2: 그렇다. CriticalSection에 진입할 때는 Thread를 확인하지만 Leave할때는 확인하지 않으며, 임의의 스레드라도 CriticalSection을 해제할 수 있다.

Q3: 어느 Thread에도 소유되지 않은 CriticalSection에 대해 LeaveCriticalSection을 호출하면 어떻게 되나?
A3: 이런 일이 벌어져선 안된다 ㅡ.ㅡ. LeaveCriticalSection을 호출하면 LockCount가 초기값인 -1에서 하나 더 감소하여 -2가 된다. 이 상태에서는 LeaveCriticalSection을 호출했던 스레드를 포함하여 어떠한 스레드도 EnterCriticalSection을 할 수 없게 된다. (시도하면 Block된다.)
이런 경우 CriticalSection을 삭제하고 다시 만드는 방법밖에 없다.

Q4: CriticalSection을 소유한 Thread가 죽어버리면 CriticalSection은 Lock이 풀릴까?
A4: 풀리지 않는다. (반면에 커널객체인 Mutex나 Event 등은 소유한 Process가 죽으면 소멸된다.) 따라서 이런 일이 벌어지면 Application이 Hang 걸려버리는 경우가 생긴다. 단, 위에서 언급한 바와 같이 소유한 Thread가 죽어버린 CriticalSection을 제 3의 Thread가 LeaveCriticalSection 해줄 수는 있다.

※ Mutex의 경우 해당 개체를 소유한 Thread가 죽으면 자동으로 Signaled 상태로 변경된다. 즉, 저절로 Lock이 풀리게 된다. 이때 WaitForSingleObject()로 대기중이던 스레드는 함수 리턴값으로 WAIT_ABANDONDED 을 받게 된다. (CriticalSectioin과 Mutex의 차이)

출처 : http://kuaaan.tistory.com/99
Posted by 패스맨

댓글을 달아 주세요

http://www.jegerlehner.ch/intel/opcode.html

TRANSFER
Name Comment Syntax
MOV Move (copy) MOV Dest,Source
XCHG Exchange XCHG Op1,Op2
STC Set Carry STC
CLC Clear Carry CLC
CMC Complement Carry CMC
STD Set Direction STD
CLD Clear Direction CLD
STI Set Interrupt STI
CLI Clear Interrupt CLI
PUSH Push onto stack PUSH Source
PUSHF Push flags PUSHF
PUSHA Push all general registers PUSHA
POP Pop from stack POP Dest
POPF Pop flags POPF
POPA Pop all general registers POPA
CBW Convert byte to word CBW
CWD Convert word to double CWD
CWDE Conv word extended double CWDE
IN Input IN Dest, Port
OUT Output OUT Port, Source

ARITHMETIC
Name Comment Syntax
ADD Add ADD Dest,Source
ADC Add with Carry ADC Dest,Source
SUB Subtract SUB Dest,Source
SBB Subtract with borrow SBB Dest,Source
DIV Divide (unsigned) DIV Op
IDIV Signed Integer Divide IDIV Op
MUL Multiply (unsigned) MUL Op
IMUL Signed Integer Multiply IMUL Op
INC Increment INC Op
DEC Decrement DEC Op
CMP Compare CMP Op1,Op2
SAL Shift arithmetic left SAL Op,Quantity
SAR Shift arithmetic right SAR Op,Quantity
RCL Rotate left through Carry RCL Op,Quantity
RCR Rotate right through Carry RCR Op,Quantity
ROL Rotate left ROL Op,Quantity
ROR Rotate right ROR Op,Quantity

LOGIC
Name Comment Syntax
NEG Negate (two-complement) NEG Op
NOT Invert each bit NOT Op
AND Logical and AND Dest,Source
OR Logical or OR Dest,Source
XOR Logical exclusive or XOR Dest,Source
SHL Shift logical left SHL Op,Quantity
SHR Shift logical right SHR Op,Quantity

MISCELLANEOUS
Name Comment Syntax
NOP No operation NOP
LEA Load effective adress LEA Dest,Source
INT Interrupt INT Nr

JUMPS (general)
Name Comment Syntax
CALL Call subroutine CALL Proc
JMP Jump JMP Dest
JE Jump if Equal JE Dest
JZ Jump if Zero JZ Dest
JCXZ Jump if CX Zero JCXZ Dest
JP Jump if Parity (Parity Even) JP Dest
JPE Jump if Parity Even JPE Dest
RET Return from subroutine RET
JNE Jump if not Equal JNE Dest
JNZ Jump if not Zero JNZ Dest
JECXZ Jump if ECX Zero JECXZ Dest
JNP Jump if no Parity (Parity Odd) JNP Dest
JPO Jump if Parity Odd JPO Dest

JUMPS unsigned (Cardinal)
JA Jump if Above JA Dest
JAE Jump if Above or Equal JAE Dest
JB Jump if Below JB Dest
JBE Jump if Below or Equal JBE Dest
JNA Jump if not Above JNA Dest
JNAE Jump if not Above or Equal JNAE Dest
JNB Jump if not Below JNB Dest
JNBE Jump if not Below or Equal JNBE Dest
JC Jump if Carry JC Dest
JNC Jump if no Carry JNC Dest

JUMPS signed (Integer)
JG Jump if Greater JG Dest
JGE Jump if Greater or Equal JGE Dest
JL Jump if Less JL Dest
JLE Jump if Less or Equal JLE Dest
JNG Jump if not Greater JNG Dest
JNGE Jump if not Greater or Equal JNGE Dest
JNL Jump if not Less JNL Dest
JNLE Jump if not Less or Equal JNLE Dest
JO Jump if Overflow JO Dest
JNO Jump if no Overflow JNO Dest
JS Jump if Sign (= negative) JS Dest
JNS Jump if no Sign (= positive) JNS Dest

'Programing > asm' 카테고리의 다른 글

어셈블리어  (0) 2011.11.29
OpCode of Intel Assembly 80x86  (0) 2011.03.07
Posted by 패스맨

댓글을 달아 주세요