{"id":94985,"date":"2016-12-21T07:00:00","date_gmt":"2016-12-21T22:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=94985"},"modified":"2019-03-13T10:35:03","modified_gmt":"2019-03-13T17:35:03","slug":"20161221-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20161221-00\/?p=94985","title":{"rendered":"What is the maximum numeric value for a socket, and what is the maximum number of sockets a Windows program can create?"},"content":{"rendered":"<p>A customer had a problem with their application that used network sockets, and they wanted to know what the maximum numeric value for a socket is. &#8220;The program uses a signed integer to hold the socket descriptor, and we found in our testing that the numeric value of <code>INVALID_SOCKET<\/code> is <code>0xFFFFFFFF<\/code>. What is the maximum value?&#8221; <\/p>\n<p>In addition to being a vague question, it&#8217;s also a strange question, so we asked for more information about the problem they are having, in the hopes that we could both understand how the problem led them to asking the strange question, and so we could try to solve the problem. <\/p>\n<p>The customer explained that they have a multithreaded application that uses thousands of network sockets. After running for several days, the customer observed that socket operations are failing with <code>INVALID_SOCKET<\/code>, and <code>WSA&shy;Get&shy;Last&shy;Error<\/code> returns error 10038: <code>WSA&shy;E&shy;NOT&shy;SOCK<\/code>. Since the error is intermittent, the customer is under the impression that the application may have created so many sockets that their socket numbers have exceeded the maximum legal numeric value for a socket, resulting in the <code>INVALID_SOCKET<\/code> error. <\/p>\n<p>The customer added, &#8220;According to <a HREF=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms739169(v=vs.85).aspx\">this link<\/a>, the  maximum number of sockets that a program can use is determined at compile time by the manifest constant <code>FD_SET&shy;SIZE<\/code>. However, we cannot find where this constant is defined.&#8221; <\/p>\n<p>Okay, it&#8217;s not clear where the customer is getting the impression  that a single program cannot use more than <code>FD_SET&shy;SIZE<\/code> sockets. Indeed, the documentation they referenced says quite the opposite: <\/p>\n<blockquote CLASS=\"q\"><p>The maximum number of sockets that a Windows Sockets application can use is <strong>not<\/strong> affected by the manifest constant  FD_SETSIZE. <\/p><\/blockquote>\n<p>(Emphasis mine.) <\/p>\n<p>The documentation continues: <\/p>\n<blockquote CLASS=\"q\"><p>This value defined in the Winsock2.h header file is used in constructing the <a HREF=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms737873(v=vs.85).aspx\"><b>FD_SET<\/b><\/a> structures used with <b>select<\/b> function. The default value in Winsock2.h is 64. <\/p><\/blockquote>\n<p>Which conveniently answers the customer&#8217;s third question. <\/p>\n<p>What the <code>FD_SET&shy;SIZE<\/code> constant determines is the maximum number of sockets that can be passed in a single call to the <code>select<\/code> function. The total number of sockets available to a program is not limited by <code>FD_SET&shy;SIZE<\/code>. <\/p>\n<p>And as the documentation notes, you can make <code>FD_SET&shy;SIZE<\/code> bigger if you need to. The point is that the <code>fd_set<\/code> structure is a variable-sized structure, but for compatibility with Unix programs, it is formally defined as a fixed-size structure so that programs can pass them around. <\/p>\n<p>Okay, now back to the original question: Is it possible that the <code>socket<\/code> function is returning socket numbers that are not legal, and that&#8217;s why the program gets <code>INVALID_SOCKET<\/code> when it tries to perform socket operations on those sockets? <\/p>\n<p>This is another case of starting with the assumption that you found an operating system bug instead of starting with the assumption that you have a bug in your program. <\/p>\n<p>While it&#8217;s possible that there is a bug in the operating system code that does socket management that causes it to hand out invalid socket handles, a much more likely reason that your program is being told that it is using invalid socket handles is, um, because it is using invalid socket handles. <\/p>\n<p>Verify that the handle being passed really is a valid socket. Maybe it was closed prematurely elsewhere. Maybe there is a bug in some other part of the code that is double-closing a handle (and the second time it closes, it accidentally closed your socket handle). Or maybe there is a bug in some other part of the code that is closing an uninitialized handle variable, so it&#8217;s basically rolling the dice, and most of the time it gets <code>ERROR_INVALID_HANDLE<\/code>, but once in a while, the uninitialized handle variable happens to contain a value that numerically matches one of your socket handles, and it ended up accidentally closing your socket. <\/p>\n<p>If you really believe that the <code>socket<\/code> function is returning invalid sockets, I guess you can add debugging code that takes the return value of every call to <code>socket<\/code> and (if it is not <code>INVALID_SOCKET<\/code> indicating that the system could not create a socket) call <code>getsockopt<\/code> to read an arbitrary-selected socket option, and see whether it fails with  <code>WSA&shy;E&shy;NOT&shy;SOCK<\/code>. <\/p>\n<p>I bet it won&#8217;t. The socket handle was probably good at the point the system gave it to you. You probably did something to make it go bad. Application Verifier can help you find out what. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>You can create as many as you want, subject to the usual resource constraints.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-94985","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>You can create as many as you want, subject to the usual resource constraints.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/94985","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=94985"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/94985\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=94985"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=94985"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=94985"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}