使用线程时出现套接字问题

Zvi*_*ika 5 .net sockets multithreading socketexception

有人可以解释一下为什么以下代码不起作用?

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace SocketThreadingTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread t = new Thread(delegate()
            {
                BeginConnect(new IPEndPoint("some address"));
            });
            t.Start();

            Console.ReadKey();
        }

        public static void BeginConnect(IPEndPoint address)
        {
            try
            {
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.BeginConnect(address, ConnectCallback, socket);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

        private static void ConnectCallback(IAsyncResult ar)
        {
            Socket sock = (Socket)ar.AsyncState;
            try
            {
                sock.EndConnect(ar);
                Console.WriteLine("Connected {0}", sock.LocalEndPoint);

                sock.Send(Encoding.UTF8.GetBytes("Hello"));

                Console.WriteLine("success");
                sock.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("send ex " + ex);

                if (sock != null)
                    sock.Close();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是(注意套接字的本地端点):

Connected 0.0.0.0:28142
send ex System.Net.Sockets.SocketException: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram
 socket using a sendto call) no address was supplied
   at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, So
cketFlags socketFlags)
   at System.Net.Sockets.Socket.Send(Byte[] buffer)
   at SocketThreadingTest.Program.ConnectCallback(IAsyncResult ar) in Program.cs:line 44
Run Code Online (Sandbox Code Playgroud)

当然,当我不使用线程并直接调用BeginConnect时,它工作正常.更令人费解的是,添加一个足够长(1秒)的Thread.Sleep它也可以正常工作.有任何想法吗?谢谢.

Geo*_*ton 0

您的 IPEndPoint 应该包含一个端口——我什至不确定您的 EndPoint 将如何编译,因为它是必需的。您可以将端口作为 IPEndAddress 的第二个参数提供,或修改 BeginConnect 方法,如下所示:

 socket.BeginConnect(address, [port], ConnectCallback, socket); 
Run Code Online (Sandbox Code Playgroud)

...其中 [port] 表示服务器上的侦听端口。