성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
[공진영] 안녕하세요 좋은글 감사합니다. 현재 제가 wpf로 관제 모...
글쓰기
제목
이름
암호
전자우편
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# - IPv4, IPv6를 모두 지원하는 서버 소켓 생성 방법</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;' > using (Socket sock = <span style='color: blue; font-weight: bold'>new Socket(SocketType.Stream, ProtocolType.Tcp)</span>) { sock.Bind(new IPEndPoint(<span style='color: blue; font-weight: bold'>IPAddress.IPv6Any</span>, 9982)); // ...[생략]... } </pre> <br /> 보통 Socket 생성자에 AddressFamily를 함께 지정하는데요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // IPv4 Socket sock = new Socket(<span style='color: blue; font-weight: bold'>AddressFamily.InterNetwork</span>, SocketType.Stream, ProtocolType.Tcp); // IPv6 Socket sock = new Socket(<span style='color: blue; font-weight: bold'>AddressFamily.InterNetworkV6</span>, SocketType.Stream, ProtocolType.Tcp); </pre> <br /> <a target='tab' href='https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.-ctor#system-net-sockets-socket-ctor(system-net-sockets-sockettype-system-net-sockets-protocoltype)'>(.NET 4.5부터 지원하는) 저걸 생략한 소켓 생성자</a>의 경우,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public Socket(SocketType socketType, ProtocolType protocolType) : this(<span style='color: blue; font-weight: bold'>OSSupportsIPv6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork</span>, socketType, protocolType) { if (OSSupportsIPv6) { <span style='color: blue; font-weight: bold'>DualMode = true;</span> } } </pre> <br /> 보는 바와 같이 운영체제가 IPv6를 지원하는 경우라면 기본적으로 InterNetworkV6로 초기화가 됩니다. 그러면서 동시에 (.NET 4.5부터 지원하는) <a target='tab' href='https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.dualmode'>DualMode 속성</a>이 true로 바뀌는데요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // NOTE: on *nix, the OS IP stack changes a dual-mode socket back to a // normal IPv6 socket once the socket is bound to an IPv6-specific // address. This can cause behavioral differences in code that checks // the value of DualMode (e.g. the checks in CanTryAddressFamily). public bool DualMode { get { if (AddressFamily != AddressFamily.InterNetworkV6) { return false; } return ((int)GetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only)! == 0); } set { if (AddressFamily != AddressFamily.InterNetworkV6) { throw new NotSupportedException(SR.net_invalidversion); } <span style='color: blue; font-weight: bold'>SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, value ? 0 : 1);</span> } } </pre> <br /> 즉, SocketOptionName.IPv6Only 옵션을 끄는 역할을 합니다. only 옵션을 껐다는 것은 IPv6/IPv4 듀얼 모드로 동작한다는 것을 의미합니다. 간단하죠? ^^ 따라서 위와 같이 소켓을 생성하는 것은 다음과 같이 바꿔서 표현할 수도 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using (Socket sock = new Socket(<span style='color: blue; font-weight: bold'>AddressFamily.InterNetworkV6</span>, SocketType.Stream, ProtocolType.Tcp)) { // Dual Mode Sockets – Never create an IPv4 Socket again // <a target='tab' href='https://devblogs.microsoft.com/dotnet/dual-mode-sockets-never-create-an-ipv4-socket-again/'>https://devblogs.microsoft.com/dotnet/dual-mode-sockets-never-create-an-ipv4-socket-again/</a> <span style='color: blue; font-weight: bold'>sock.DualMode = true;</span> sock.Bind(new IPEndPoint(IPAddress.IPv6Any, 9982)); // ...[생략]... } </pre> <br /> 기왕이면 코드가 단순한 것이 좋으니 첫 번째 유형으로 쓰고, 단지 그것이 어떤 의미인지만 이 글을 통해 알아두시면 되겠습니다. ^^<br /> <br /> 참고로, DualMode는 Vista 이후의 운영체제에서만 지원됩니다. 만약 Vista 미만의 운영체제를 지원해야 한다면 IPv4, IPv6 소켓을 각각 생성해 바인딩시켜야 합니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> IPv6 소켓을 사용하면서 주소는 IPv4를 지정하면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Socket sock = new Socket(<span style='color: blue; font-weight: bold'>AddressFamily.InterNetworkV6</span>, SocketType.Stream, ProtocolType.Tcp); sock.Bind(new IPEndPoint(<span style='color: blue; font-weight: bold'>IPAddress.Any</span>, 18000)); </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;' > Unhandled exception. System.Net.Sockets.SocketException (10014): The system detected an invalid pointer address in attempting to use a pointer argument in a call. at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName) at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress) at System.Net.Sockets.Socket.Bind(EndPoint localEP) ...[생략]... </pre> <br /> <hr style='width: 50%' /><br /> <br /> DualMode 속성을 지원하지 않는 .NET 4.5 미만에서는 이렇게!<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Tired of creating sockets for each protocol, to make your application listen on all addresses for a given port? ; <a target='tab' href='https://web.archive.org/web/20130909044601/http://blogs.msdn.com/b/malarch/archive/2005/11/18/494769.aspx'>https://web.archive.org/web/20130909044601/http://blogs.msdn.com/b/malarch/archive/2005/11/18/494769.aspx</a> </pre> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> There is no more pain. Here is a cool new feature supported in Vista and Windows Server Longhorn. By just setting a socketoption, you will be able to use the same socket to accept connections from both ipv4 and ipv6 clients.<br /> <br /> The following sample code shows how to configure the server socket.<br /> </div><br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > static void Main(string[] args) { Socket sock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); sock.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, 0); sock.Bind(new IPEndPoint(IPAddress.IPv6Any, 8000)); sock.Listen(4); Socket client = sock.Accept(); Console.WriteLine("Client has connected successfully with the server"); } </pre> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> Create an IPv6 socket. Set the socket option IPV6_V6Only to false (by default it is true), to enable the socket to accept connections from ipv4 addresses too. Bind and Listen as usual. Now both ipv4 and ipv6 clients can connect to it<br /> More info can be found in <a target='tab' href='http://www.ietf.org/rfc/rfc3493.txt'>http://www.ietf.org/rfc/rfc3493.txt</a>.<br /> <br /> This is because Vista has a completely redesigned TCP/IP stack.<br /> <br /> Whereas Windows XP and Win2k3 have a dual stack architecture, i.e., the Tcp, Udp layer is separate for both ipv4 and ipv6 protocols, Vista supports the dual IP layer architecture. That is, Only a single Tcp, Udp layer is present for both the ipv4 and ipv6 protocols.<br /> </div><br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1911
(왼쪽의 숫자를 입력해야 합니다.)