无法连接到本地计算机上的套接字

Shr*_*roy 2 sockets f#

我在这里做了一个简单的C#代码示例翻译:

let socket_CreateBindListen (sv_ : string) (pt_ : int) : Socket option =
    let (he : IPHostEntry) = Dns.GetHostEntry(sv_)
    let rsock, ipe =
        he.AddressList
        |> Seq.map (fun s ->
            let (ipe2 : IPEndPoint) = new IPEndPoint (s, pt_)
            let (rsock2 : Socket) = new Socket (ipe2.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
            rsock2.Connect ipe2 ///// <---- No connection could be made because the target machine actively refused it
            rsock2, ipe2)
        |> Seq.find (fun (s, t) -> s.Connected)
    try
        rsock.Bind ipe
        rsock.Listen 10
        printfn "%s now listening on port %d" sv_ pt_
        Some (rsock)
    with
        | _ ->
            printfn "Failed to connect to %s on port %d" sv_ pt_
            None

socket_CreateBindListen "127.0.0.1" 50000
Run Code Online (Sandbox Code Playgroud)

我确保首先在我的机器上打开端口50000,用于TCP的入站和出站连接.(我甚至尝试完全禁用防火墙.)似乎没有什么工作.我一直收到错误消息:

No connection could be made because the target machine actively refused it.
Run Code Online (Sandbox Code Playgroud)

我正在使用Windows 8.我真的很感激我可能会尝试的其他一些指示.

在此先感谢您的时间.


编辑

我希望我没有违反任何StackOverflow的发布政策,在博客上写下我的进展.

我已将代码更新为以下内容:

let socket_CreateBindListen (sv_ : string) (pt_ : int) : Socket option =
    let (he : IPHostEntry) = Dns.GetHostEntry(sv_)
    let rsock, ipe =
        he.AddressList
        |> Seq.map (fun s ->
            let (ipe2 : IPEndPoint) = new IPEndPoint (s, pt_)
            let (rsock2 : Socket) = new Socket (ipe2.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
            try
                rsock2.Connect ipe2
                rsock2, ipe2
            with
                | _ ->
                    null, null)
        |> Seq.find (fun (s, t) -> (s <> null) && (s.Connected))
    try
        rsock.Bind ipe
        rsock.Listen sbl
        printfn "%s now listening on port %d" sv_ pt_
        Some (rsock)
    with
        | _ ->
            printfn "Failed to connect to %s on port %d" sv_ pt_
            None
Run Code Online (Sandbox Code Playgroud)

现在我收到以下错误:

KeyNotFoundException was unhandled
An unhandled exception of type 'System.Collections.Generic.KeyNotFoundException' occurred in FSharp.Core.dll
Run Code Online (Sandbox Code Playgroud)

我在Google和Bing上广泛关注,没有任何运气.


编辑2

根据请求Jack P.,这里是输出netstat -a,以及执行二进制文件时发生的情况:

PS C:\Users\shredderroy> netstat -a

Active Connections

  Proto  Local Address          Foreign Address        State
  TCP    0.0.0.0:80             SPEEDMACHINE:0         LISTENING
  TCP    0.0.0.0:135            SPEEDMACHINE:0         LISTENING
  TCP    0.0.0.0:445            SPEEDMACHINE:0         LISTENING
  TCP    0.0.0.0:2179           SPEEDMACHINE:0         LISTENING
  TCP    0.0.0.0:49152          SPEEDMACHINE:0         LISTENING
  TCP    0.0.0.0:49153          SPEEDMACHINE:0         LISTENING
  TCP    0.0.0.0:49154          SPEEDMACHINE:0         LISTENING
  TCP    0.0.0.0:49155          SPEEDMACHINE:0         LISTENING
  TCP    0.0.0.0:49156          SPEEDMACHINE:0         LISTENING
  TCP    192.168.0.139:139      SPEEDMACHINE:0         LISTENING
  TCP    192.168.0.139:49159    bn1wns2011708:https    ESTABLISHED
  TCP    192.168.0.139:49167    vc-in-f108:imaps       ESTABLISHED
  TCP    192.168.0.139:49171    vc-in-f108:imaps       ESTABLISHED
  TCP    192.168.0.139:49239    a23-67-250-112:http    CLOSE_WAIT
  TCP    [::]:80                SPEEDMACHINE:0         LISTENING
  TCP    [::]:135               SPEEDMACHINE:0         LISTENING
  TCP    [::]:445               SPEEDMACHINE:0         LISTENING
  TCP    [::]:2179              SPEEDMACHINE:0         LISTENING
  TCP    [::]:49152             SPEEDMACHINE:0         LISTENING
  TCP    [::]:49153             SPEEDMACHINE:0         LISTENING
  TCP    [::]:49154             SPEEDMACHINE:0         LISTENING
  TCP    [::]:49155             SPEEDMACHINE:0         LISTENING
  TCP    [::]:49156             SPEEDMACHINE:0         LISTENING
  UDP    0.0.0.0:500            *:*
  UDP    0.0.0.0:4500           *:*
  UDP    0.0.0.0:5355           *:*
  UDP    127.0.0.1:53194        *:*
  UDP    127.0.0.1:60316        *:*
  UDP    127.0.0.1:61644        *:*
  UDP    192.168.0.139:137      *:*
  UDP    192.168.0.139:138      *:*
  UDP    [::]:500               *:*
  UDP    [::]:4500              *:*
  UDP    [::]:5355              *:*
  UDP    [fe80::b193:4f6:d053:6324%20]:546  *:*
PS C:\Users\shredderroy> cd "C:\Users\shredderroy\Documents\Visual Studio 2012\Projects\FSharp\SocketTests_Server\SocketTests_Server\bin\Debug
"
PS C:\Users\shredderroy\Documents\Visual Studio 2012\Projects\FSharp\SocketTests_Server\SocketTests_Server\bin\Debug> .\SocketTests_Server.exe
Unhandled Exception: System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it [::1]:50000
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
   at SocketTests_Server.TestModule_1.heo@22.Invoke(IPAddress s) in C:\Users\shredderroy\Documents\Visual Studio 2012\Projects\FSharp\SocketTests_Server\SocketTests_Server\TestModule_1.fs:line 25 at Microsoft.FSharp.Collections.SeqModule.TryFind[T](FSharpFunc`2 predicate, IEnumerable`1 source)
   at SocketTests_Server.TestModule_1.socket_CreateBindListen_1(String sv_, Int32 pt_) in C:\Users\shredderroy\Documents\Visual Studio
2012\Projects\FSharp\SocketTests_Server\SocketTests_Server\TestModule_1.fs:line 20
   at SocketTests_Server.Program.Main(String[] args) in C:\Users\shredderroy\Documents\Visual Studio 2012\Projects\FSharp\SocketTests_Server\SocketTests_Server\Program.fs:line 9
PS C:\Users\shredderroy\Documents\Visual Studio 2012\Projects\FSharp\SocketTests_Server\SocketTests_Server\bin\Debug>
Run Code Online (Sandbox Code Playgroud)

我要继续努力.到目前为止,我已将我的程序添加SocketTests_Server.exe到Windows防火墙中允许的程序列表中,打开了入站和出站连接的相关端口,完全禁用了防火墙 - 一切都无济于事.

Joh*_*mer 6

我认为发生的事情是你连接两次,其中一个地址连接正常.然后,您的代码将继续查看剩余的地址并尝试再次连接.

您的代码缺少break与C#代码相同的代码.

一些可能的解决方

  1. 使用while循环而不是 Seq.map
  2. 在里面使用引用变量 map
  3. 压缩所有代码Seq.find并删除对map的调用(可能是最优雅的)

  • @Shredderroy Breakpoints可能有点搞笑F#lambdas有时候 - 尝试放一个`printfn` (3认同)

Jac*_* P. 5

我翻译了你链接的页面中的代码 - 它编译,但我还没有尝试运行它.

open System
open System.Text
open System.Net
open System.Net.Sockets

let connectSocket (server : string, port : int) : Socket option =
    // Get host related information.
    let hostEntry = Dns.GetHostEntry server

    // Loop through the AddressList to obtain the supported AddressFamily. This is to avoid 
    // an exception that occurs when the host IP Address is not compatible with the address family 
    // (typical in the IPv6 case). 
    hostEntry.AddressList
    |> Seq.tryPick (fun address ->
        let ipe2 = IPEndPoint (address, port)
        let rsock2 = new Socket (ipe2.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
        rsock2.Connect ipe2
        if rsock2.Connected then
            Some rsock2
        else None)

// This method requests the home page content for the specified server. 
let socketSendReceive (server : string, port : int) : string =
    let request =
        sprintf "GET / HTTP/1.1\r\nHost: %s\r\nConnection: Close\r\n\r\n" server
    let bytesSent =
        Encoding.ASCII.GetBytes request
    let bytesReceived = Array.zeroCreate 256

    // Create a socket connection with the specified server and port.
    match connectSocket (server, port) with
    | None ->
        "Connection failed"
    | Some s ->
        // Send request to the server.
        s.Send (bytesSent, Array.length bytesSent, SocketFlags.None)
        |> ignore

        // Receive the server home page content. 
        let mutable bytes = 0
        let mutable page =
            sprintf "Default HTML page on %s:\r\n" server

        // The following will block until the page is transmitted. 
        while bytes > 0 do
            bytes <- s.Receive (bytesReceived, Array.length bytesReceived, SocketFlags.None)
            page <- page + Encoding.ASCII.GetString (bytesReceived, 0, bytes)

        page

//
let main args =
    let port = 80

    let host =
        if Array.isEmpty args then
            // If no server name is passed as argument to this program,  
            // use the current host name as the default.
            Dns.GetHostName ()
        else
            args.[0]

    socketSendReceive (host, port)
    |> Console.WriteLine
Run Code Online (Sandbox Code Playgroud)

编辑:我做了一点挖掘,"主动拒绝"是该错误消息的关键,根据:没有连接可以,因为目标机器主动拒绝它.简而言之,仔细检查您尝试连接的服务器是否设置正确; 当主动拒绝连接时,没有防火墙问题 - 服务器实际上拒绝您的连接.

如果您完全确定服务器设置正确,那么您可以尝试最后一件事.根据Socket Connection Is Actively Refused(MSDN论坛),您可能需要使用IPAddress.NetworkToHostOrder方法为IPEndPoint正确设置端口值.在这种情况下,只需将其添加为我的connectSocket函数中的第一行(上图):

let port = IPAddress.NetworkToHostOrder port
Run Code Online (Sandbox Code Playgroud)

编辑2:查看netstat您发布的信息 - LISTENING端口50000 上没有服务器.如果您确定服务器软件设置正确,请确保它使用您想要的端口(而不仅仅是选择随机端口).