๋ฐ์ํ
- ์์ผ ์ธํฐํ์ด์ค๋ L7๊ณผ L4 layer ์ฌ์ด์ ์์นํ๋ค.
- HTTP๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ ์ ์ก ๋ฐ ์์ ์ ์์ํ๊ธฐ ์ ์ ๋จผ์ Connection์ ์ค์ ํด์ผ ํ๋ค
- Connection์ ์ค์ ํ๊ธฐ ์ํด ์ ํ๋ฆฌ์ผ์ด์ ๊ณ์ธต์ TCP ์ ์ก ๊ณ์ธต ํ๋กํ ์ฝ์ ์ฌ์ฉํ๋ค
- TCP ์ฐ๊ฒฐ์ ์์ํ๊ธฐ ์ํด ํด๋ผ์ด์ธํธ๋ ์์ผ์ ์์ฑํ๋ค.
- ์์ผ์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๊ณ ๋ฐ๋ ์ฌ์ํจ๊ณผ ๊ฐ๋ค๊ณ ์๊ฐํ ์ ์๋ค.
- ์ค์ HttpClient ์ฝ๋๋ฅผ ๋ณด๋ฉด doConnect๋ก Socket ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ถ๋ถ์ ๋ณผ ์ ์๋ค
- ์ฐธ๊ณ ๋ก ์๋ฐ์์ Socket ๊ฐ์ฒด๋ TCP ํต์ ์ ํ๊ณ DatagramSocket ๊ฐ์ฒด๋ UDP ํต์ ์ ํ๋ค.
protected Socket serverSocket = null;
- ์๋ฒ์์ผ์ ๋ด๋ถ์ ์ผ๋ก 2๊ฐ์ Queue๋ฅผ ๊ฐ์ง๋ค.
- incomplete queue : ์๋ฒ๋ก ๋ค์ด์จ ์ฐ๊ฒฐ ์์ฒญ๋ค์ ์ ์ฅ
- complete queue : ์ต์ข ์ ์ผ๋ก ์ฐ๊ฒฐ๋ ์ํ๊ฐ ๋ ์์ฒญ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ํ
์ฐธ๊ณ - Java Socket ๋ด๋ถ ๊ตฌํ
๋ชจ๋ ํ ํด๋์ค์ ์๋ ๊ฑด ์๋๊ณ , ํ๊ณ ๊ฐ๋ค๊ฐ ์ค์ํ ๋ถ๋ถ๋ง ์ ์ด๋์
// ํฉํ ๋ฆฌ ์์ผ๋ฉด SocksSocketImpl์ผ๋ก Impl ์์ฑํด์ ์ธํ
void setImpl() {
if (factory != null) {
impl = factory.createSocketImpl();
checkOldImpl();
} else {
// No need to do a checkOldImpl() here, we know it's an up to date
// SocketImpl!
impl = new SocksSocketImpl();
}
if (impl != null)
impl.setSocket(this);
}
// SocksSocketImpl์ AbstractPlainSocketImpl์ getInputStream ํธ์ถ๋จ
protected synchronized InputStream getInputStream() throws IOException {
synchronized (fdLock) {
if (isClosedOrPending())
throw new IOException("Socket Closed");
if (shut_rd)
throw new IOException("Socket input is shutdown");
if (socketInputStream == null)
socketInputStream = new SocketInputStream(this);
}
return socketInputStream;
}
// socketInputStream.read ํ๊ณ ๊ฐ๋ค ๋ณด๋ฉด
// socketReadํ๋ ๋ถ๋ถ์ด ์๋๋ฐ ์ฌ๊ธฐ์ ์ธํ
ํ timeout๊ฐ ์ฌ์ฉ
private int socketRead(FileDescriptor fd,
byte b[], int off, int len,
int timeout)
throws IOException {
return socketRead0(fd, b, off, len, timeout);
}
int read(byte b[], int off, int length, int timeout) throws IOException {
int n;
// EOF already encountered
if (eof) {
return -1;
}
// connection reset
if (impl.isConnectionReset()) {
throw new SocketException("Connection reset");
}
// bounds check
if (length <= 0 || off < 0 || length > b.length - off) {
if (length == 0) {
return 0;
}
throw new ArrayIndexOutOfBoundsException("length == " + length
+ " off == " + off + " buffer length == " + b.length);
}
boolean gotReset = false;
// acquire file descriptor and do the read
FileDescriptor fd = impl.acquireFD();
try {
n = socketRead(fd, b, off, length, timeout);
if (n > 0) {
return n;
}
} catch (ConnectionResetException rstExc) {
gotReset = true;
} finally {
impl.releaseFD();
}
/*
* We receive a "connection reset" but there may be bytes still
* buffered on the socket
*/
if (gotReset) {
impl.setConnectionResetPending();
impl.acquireFD();
try {
n = socketRead(fd, b, off, length, timeout);
if (n > 0) {
return n;
}
} catch (ConnectionResetException rstExc) {
} finally {
impl.releaseFD();
}
}
/*
* If we get here we are at EOF, the socket has been closed,
* or the connection has been reset.
*/
if (impl.isClosedOrPending()) {
throw new SocketException("Socket closed");
}
if (impl.isConnectionResetPending()) {
impl.setConnectionReset();
}
if (impl.isConnectionReset()) {
throw new SocketException("Connection reset");
}
eof = true;
return -1;
}
- new Socket() -> ๋ด๋ถ์ ์ผ๋ก SocketInputStream ์ฌ์ฉํด์ read()
- read()
- file descriptor๋ฅผ ์ป์ด์ socketRead
- ์์ฑํ ์์ผ ๊ฐ์ฒด์ timeout๊ฐ์ ์ง์ ํ ์ ์๋๋ฐ, socketReadํ ๋ ์ฌ์ฉํ๋ ๋ถ๋ถ ์กด์ฌ
- socketRead0 ๋ค์ดํฐ๋ธ ์ฝ๋
- ๋ค๋ฅธ ๊ตฌํ์ฒด์์๋ ๋ช ์์ ์ผ๋ก System.currentTimeMillis ์ฌ์ฉํด์ timeout ๋๊ฑด์ง ์ฒดํฌํ๋ ๋ก์ง ํ์ธ๋จ
- ์์ฑํ ์์ผ ๊ฐ์ฒด์ timeout๊ฐ์ ์ง์ ํ ์ ์๋๋ฐ, socketReadํ ๋ ์ฌ์ฉํ๋ ๋ถ๋ถ ์กด์ฌ
- ์ฐธ๊ณ ๋ก ์ฝ์ ์ ์๋ ๋ฐ์ดํฐ๊ฐ ์์ ๋๊น์ง blocking (๋จ, soTimeout ์๊ฐ๋งํผ๋ง blocking -> socketTimeoutException ๋ฐ์)
- file descriptor๋ฅผ ์ป์ด์ socketRead
๐ Reference
๋๋ณด๊ธฐ
๋ฐ์ํ