gpt4 book ai didi

.net - 使用线程时的socket问题

转载 作者:行者123 更新时间:2023-12-03 11:49:26 24 4
gpt4 key购买 nike

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

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();
}
}
}
}

输出是(注意套接字的本地端点):
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

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

最佳答案

使用单独的 Thread 和 BeginConnect 哪个有意义?
如果您创建单独的线程(最好使用线程池),为什么要使用异步连接(在这种情况下,将从线程池中获取单独的线程)?

有几种选择:
使用 ThreadPool 和 Socket.Connect

class Program {

static void Connect(object o)
{
IPEndPoint address = (IPEndPoint)o;
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(address);
Console.WriteLine("Connected {0}", socket.LocalEndPoint);
socket.Send(Encoding.UTF8.GetBytes("Hello"));
Console.WriteLine("success");
socket.Close();
}

static void Main(string[] args)
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, 5111);
ThreadPool.QueueUserWorkItem(Connect, endPoint);
Console.ReadKey();
}
}

使用没有单独线程的 BeginConnect。
class Program {

static void Main(string[] args)
{
BeginConnect(new IPEndPoint(IPAddress.Loopback, 5111));
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();
}
}
}

使用带有单独线程的 BeginConnect:
class Program
{

static void Main(string[] args)
{
Thread t = new Thread(delegate()
{
BeginConnect(new IPEndPoint(IPAddress.Loopback, 5111));
});
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();
}
}
}

关于.net - 使用线程时的socket问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2094185/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com