성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# - 리눅스 환경에서 클라이언트 소켓의 ephemeral port 재사용</h1> <p> 윈도우의 경우,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 윈도우 환경에서 클라이언트 소켓의 최대 접속 수 (4) - ReuseUnicastPort를 이용한 포트 고갈 문제 해결 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12435'>https://www.sysnet.pe.kr/2/0/12435</a> </pre> <br /> AutoReusePortRangeStartPort/AutoReusePortRangeNumberOfPorts 설정을 통해 5-tuple 구분을 할 수 있었는데요, 그렇다면 .NET Core/5로 리눅스에서 실행하면 어떻게 바뀌는 걸까요?<br /> <br /> 일단 검색해 보면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Ephemeral port exhaustion and how to avoid it ; <a target='tab' href='https://making.pusher.com/ephemeral-port-exhaustion-and-how-to-avoid-it/'>https://making.pusher.com/ephemeral-port-exhaustion-and-how-to-avoid-it/</a> </pre> <br /> 리눅스의 경우 기본적으로 5-tuple로 구분을 하고 있습니다. 그래도 혹시 모르니 눈으로 직접 확인을 해보겠습니다. ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> (이 글의 테스트 환경은 우분투 20.04 + .NET 5입니다.)<br /> <br /> 이번에도 역시 테스트의 편의를 위해 로컬 포트 수를 줄이려고 했는데요, 제가 리눅스를 잘 몰라 포트 수 줄이는 게 좀 서툴군요. ^^; 우선 다음과 같이 sysctl을 이용해 봤는데,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > $ <span style='color: blue; font-weight: bold'>sysctl net.ipv4.ip_local_port_range</span> net.ipv4.ip_local_port_range = 32768 60999 $ <span style='color: blue; font-weight: bold'>sudo sysctl -w net.ipv4.ip_local_port_range="32768 33768"</span> </pre> <br /> 재부팅하고 나면 다시 32768 ~ 60999로 바뀝니다. 검색해 보면 아래와 같은 방법도 보이는데,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > $ <span style='color: blue; font-weight: bold'>cat /proc/sys/net/ipv4/ip_local_port_range</span> 32768 60999 $ <span style='color: blue; font-weight: bold'>sudo echo "32768 33768" > /proc/sys/net/ipv4/ip_local_port_range</span> bash: /proc/sys/net/ipv4/ip_local_port_range: Permission denied </pre> <br /> 안됩니다. ^^; 다시 검색을 해보면, Redhat 문서지만 /etc/sysctl.conf를 편집하는 방법도 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 6.7. The ip_local_port_range parameters ; <a target='tab' href='https://tldp.org/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-v1.3/chap6sec70.html'>https://tldp.org/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-v1.3/chap6sec70.html</a> </pre> <br /> 그래서 "/etc/sysctl.conf" 파일에 다음의 설정을 추가 후,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > # Allowed local port range net.ipv4.ip_local_port_range = 32768 33768 </pre> <br /> 서비스 재시작을 하라고 하는데,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > $ <span style='color: blue; font-weight: bold'>/etc/rc.d/init.d/network restart</span> bash: /etc/rc.d/init.d/network: No such file or directory </pre> <br /> Ubuntu라 그런지 다른 듯하군요, 달리 방법을 모르니 그냥 "sudo reboot now"를 했고 다행히 반영이 잘 되었습니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > $ <span style='color: blue; font-weight: bold'>cat /proc/sys/net/ipv4/ip_local_port_range</span> 32768 33768 </pre> <br /> (혹시 저 방법 말고 아시는 분은 덧글 부탁드립니다. ^^)<br /> <br /> <hr style='width: 50%' /><br /> <br /> 자, 그래서 테스트를 위해 서버와 클라이언트 2개를 실행하면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > $ <span style='color: blue; font-weight: bold'>dotnet ConsoleApp1.dll</span> # of 15000: 0, 15001: 0 # of 15000: 0, 15001: 0 # of 15000: 0, 15001: 0 # of 15000: 1000, 15001: 0 # of 15000: 1000, 15001: 0 # of 15000: 1000, 15001: 0 # of 15000: 1000, 15001: 1000 # of 15000: 1000, 15001: 1000 # of 15000: 1000, 15001: 1000 </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > $ <span style='color: blue; font-weight: bold'>dotnet ConsoleApp2.dll 127.0.0.1 15000 1001</span> [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>33590</span>-[::ffff:127.0.0.1]:15000 [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>33592</span>-[::ffff:127.0.0.1]:15000 ...[생략]... [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>33759</span>-[::ffff:127.0.0.1]:15000 [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>33761</span>-[::ffff:127.0.0.1]:15000 [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>33763</span>-[::ffff:127.0.0.1]:15000 [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>33765</span>-[::ffff:127.0.0.1]:15000 [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>33767</span>-[::ffff:127.0.0.1]:15000 [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>32769</span>-[::ffff:127.0.0.1]:15000 System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (99): Cannot assign requested address [::ffff:127.0.0.1]:15000 at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress) at System.Net.Sockets.Socket.Connect(EndPoint remoteEP) at System.Net.Sockets.TcpClient.Connect(IPEndPoint remoteEP) at System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port) --- End of stack trace from previous location --- at System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port) at ConsoleApp2.Program.Main(String[] args) in C:\temp\ConsoleApp2\Program.cs:line 23 <span style='color: blue; font-weight: bold'>1000</span> </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > $ <span style='color: blue; font-weight: bold'>dotnet ConsoleApp2.dll localhost 15001 1001</span> [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>32952</span>-[::ffff:127.0.0.1]:15001 [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>32954</span>-[::ffff:127.0.0.1]:15001 ...[생략]... [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>33759</span>-[::ffff:127.0.0.1]:15001 [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>33761</span>-[::ffff:127.0.0.1]:15001 [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>33763</span>-[::ffff:127.0.0.1]:15001 [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>33765</span>-[::ffff:127.0.0.1]:15001 [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>33767</span>-[::ffff:127.0.0.1]:15001 [::ffff:127.0.0.1]:<span style='color: blue; font-weight: bold'>32769</span>-[::ffff:127.0.0.1]:15001 System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (99): Cannot assign requested address [::ffff:127.0.0.1]:15001 at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress) at System.Net.Sockets.Socket.Connect(EndPoint remoteEP) at System.Net.Sockets.TcpClient.Connect(IPEndPoint remoteEP) at System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port) --- End of stack trace from previous location --- at System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port) at ConsoleApp2.Program.Main(String[] args) in C:\temp\ConsoleApp2\Program.cs:line 23 <span style='color: blue; font-weight: bold'>1000</span> </pre> <br /> 클라이언트 2개가 모두 정확히 (포트 수를 1,000개로 제한했으므로) 1,000까지 잘 생성하고, 1,001번째에서 예외가 발생합니다. 즉, 5-tuple 구분을 클라이언트 소켓에서도 별다른 설정 없이 잘 동작하고 있는 것입니다.<br /> <br /> 윈도우가 AutoReusePortRangeStartPort/AutoReusePortRangeNumberOfPorts 설정을 해야 했던 반면, 리눅스는 그냥 되니 편리하긴 합니다. ^^<br /> <br /> (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1686&boardid=331301885'>첨부 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
6130
(왼쪽의 숫자를 입력해야 합니다.)