标签: tcpclient

调用BeginAcceptTcpClient后停止TcpListener

我有这个代码......

internal static void Start()
{
    TcpListener listenerSocket = new TcpListener(IPAddress.Any, 32599);
    listenerSocket.Start();
    listenerSocket.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), null);
}
Run Code Online (Sandbox Code Playgroud)

然后我的回调函数看起来像这样......

private static void AcceptClient(IAsyncResult asyncResult)
{
    MessageHandler handler = new MessageHandler(listenerSocket.EndAcceptTcpClient(asyncResult));
    ThreadPool.QueueUserWorkItem((object state) => handler.Process());
    listenerSocket.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), null);
}
Run Code Online (Sandbox Code Playgroud)

现在,我调用BeginAcceptTcpClient,然后一段时间后我想停止服务器.为此,我一直在调用TcpListener.Stop()或TcpListener.Server.Close().然而,这两个都执行我的AcceptClient函数.这会在我调用EndAcceptTcpClient时抛出异常.围绕这个的最佳做法是什么?一旦我调用了stop,我就可以放入一个标志来停止执行AcceptClient,但我想知道我是否遗漏了一些东西.

更新1

目前我通过将代码更改为这样来修补它.

private static void AcceptClient(IAsyncResult asyncResult)
{
     if (!shutdown)
     {
          MessageHandler handler = new MessageHandler(listenerSocket.EndAcceptTcpClient(asyncResult));
          ThreadPool.QueueUserWorkItem((object state) => handler.Process());
          listenerSocket.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), null);
     }
}

private static bool shutdown = false;
internal static void Stop()
{
     shutdown = true;
     listenerSocket.Stop();
}
Run Code Online (Sandbox Code Playgroud)

更新2 …

c# sockets tcpclient

20
推荐指数
2
解决办法
3万
查看次数

如何在TcpClient类中使用SSL

在.NET框架中,有一个类TcpClient可以从电子邮件服务器中检索电子邮件.本TcpClient类有4个构造与内搭最多两个参数的服务器连接.它适用于那些不使用SSL的服务器.但是gmail或许多其他电子邮件提供商使用SSL进行IMAP.

我可以连接gmail服务器但无法使用email_id和密码进行身份验证.

我的验证用户代码是

public void AuthenticateUser(string username, string password)
{
    _imapSw.WriteLine("$ LOGIN " + username + " " + password);
    //_imapSw is a object of StreamWriter class
    _imapSw.Flush();
    Response();
}
Run Code Online (Sandbox Code Playgroud)

但是这段代码无法登录.

那么TcpClient当我必须使用SSL时,如何使用该类来检索电子邮件?

.net c# email tcpclient

20
推荐指数
1
解决办法
3万
查看次数

直接在Socket上使用TcpClient有什么好处?

我知道TcpClient是套接字类的包装器,如果使用TcpClient,我可以访问底层套接字,但是包装器究竟做了什么?

当使用TCPClient时,我需要继续调用Receive(),就像我使用套接字一样,或者包装器是否确保我的所有数据都出现?

最后,我可以在服务器和客户端上使用TcpClient来包装套接字(在使用TcpListener接受服务器上的原始连接之后)

c# sockets tcpclient

20
推荐指数
1
解决办法
1万
查看次数

关闭TcpListener和TcpClient连接的正确顺序(哪一方应该是活动关闭)

在上一个问题中读到了这个答案:

因此,启动终止的对等体 - 即首先调用close() - 将最终处于TIME_WAIT状态.[...]

但是,在服务器上处于TIME_WAIT状态的许多套接字可能会出现问题,因为它最终可能会阻止接受新连接.[...]

相反,请设计应用程序协议,以便始终从客户端启动连接终止.如果客户端总是知道它何时读取了所有剩余数据,则它可以启动终止序列.例如,浏览器在读取所有数据时可以从Content-Length HTTP标头中获知,并且可以启动关闭.(我知道在HTTP 1.1中它会保持打开一段时间以便重用,然后关闭它.)

我想使用TcpClient/TcpListener来实现它,但目前尚不清楚如何使其正常工作.

方法1:双方关闭

这是大多数MSDN示例所示的典型方式 - 双方调用Close(),而不仅仅是客户端:

private static void AcceptLoop()
{
    listener.BeginAcceptTcpClient(ar =>
    {
        var tcpClient = listener.EndAcceptTcpClient(ar);

        ThreadPool.QueueUserWorkItem(delegate
        {
            var stream = tcpClient.GetStream();
            ReadSomeData(stream);
            WriteSomeData(stream);
            tcpClient.Close();   <---- note
        });

        AcceptLoop();
    }, null);
}

private static void ExecuteClient()
{
    using (var client = new TcpClient())
    {
        client.Connect("localhost", 8012);

        using (var stream = client.GetStream())
        {
            WriteSomeData(stream);
            ReadSomeData(stream);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我运行20个客户端之后,套装软件显示了很多插座的客户端和服务器都 …

.net sockets tcplistener tcpclient

18
推荐指数
1
解决办法
5457
查看次数

不允许异步锁定

基本上,我想向tcp服务器发出多个异步请求.我目前有一个只有同步的工作客户端,并在每次网络调用时阻止UI.由于多个请求几乎可能同时发生,我尝试这样做:

private object readonly readLock = new object(); 
public async Task UpdateDetailsAsync()
{
    //I want every request to wait their turn before requesting (using the connection) 
    //to prevent a read call from catching any data from another request
    lock (readLock)
    {
        Details details = await connection.GetDetailsAsync();
        detailsListBox.Items = details;
    }
}
Run Code Online (Sandbox Code Playgroud)

我确信这不是一个很好用的锁,但这是我能想到的唯一方法,可以让电话等待轮到他们.有没有我可以用来实现这种行为的对象?我认为Monitor会是一样的所以我没有尝试(我知道他们是多线程的东西,但这就是我所熟悉的......)

c# tcpclient async-await

17
推荐指数
2
解决办法
1万
查看次数

Windows自动化telnet

我想运行一组通常在telnet中运行的命令(来自c#).

例如,我想运行以下内容

using System;
using System.Diagnostics;

namespace InteractWithConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            ProcessStartInfo cmdStartInfo = new ProcessStartInfo();
            cmdStartInfo.FileName = @"C:\Windows\System32\cmd.exe";
            cmdStartInfo.RedirectStandardOutput = true;
            cmdStartInfo.RedirectStandardError = true;
            cmdStartInfo.RedirectStandardInput = true;
            cmdStartInfo.UseShellExecute = false;
            cmdStartInfo.CreateNoWindow = true;

            Process cmdProcess = new Process();
            cmdProcess.StartInfo = cmdStartInfo;
            cmdProcess.ErrorDataReceived += cmd_Error;
            cmdProcess.OutputDataReceived += cmd_DataReceived;
            cmdProcess.EnableRaisingEvents = true;
            cmdProcess.Start();
            cmdProcess.BeginOutputReadLine();
            cmdProcess.BeginErrorReadLine();

            cmdProcess.StandardInput.WriteLine("telnet telehack.com");
            int milliseconds = 2000;
            System.Threading.Thread.Sleep(milliseconds);
            cmdProcess.StandardInput.WriteLine("exit");

            cmdProcess.StandardInput.WriteLine("exit");
            cmdProcess.WaitForExit();
        }

        static void cmd_DataReceived(object sender, DataReceivedEventArgs e)
        {
            Console.WriteLine(e.Data);
        } …
Run Code Online (Sandbox Code Playgroud)

c# telnet tcpclient

17
推荐指数
2
解决办法
2145
查看次数

如何让内核在TCP套接字编程中选择范围(1024,5000)中的端口号

当我运行以下代码时:

struct   sockaddr_in sin;
int addrlen;   
addrlen=sizeof(sin);   
memset(&sin, 0, sizeof(sin));  
sin.sin_family = AF_INET;  
sin.sin_addr.s_addr=inet_addr("123.456.789.112");  
sin.sin_port=htons(0); // so that the kernel reserves a unique port for us  
sd_server = socket(PF_INET, SOCK_STREAM, 0);  
bind(sd_server, (struct sockaddr *) &sin, sizeof(sin));  
getsockname(sd_server,(struct sockaddr*)&sin,&addrlen);  
port=ntohs(sin.sin_port); 
printf("port number = %d\n",port);
Run Code Online (Sandbox Code Playgroud)

根据套接字,我必须得到1024到5000之间的端口号,但是我的端口号大约是30,000.
我该怎么办?

sockets kernel tcplistener tcpclient

15
推荐指数
2
解决办法
3万
查看次数

TcpClient如何实现IDisposable并且没有公共Dispose方法?

就像标题说的那样:

TcpClient如何实现IDisposable并且没有公共Dispose方法?

.net idisposable tcpclient

15
推荐指数
1
解决办法
907
查看次数

BeginReceive/BeginRead超时

我正在使用NetworkStream和TcpClient使用BeginRead异步接收数据.我需要对此操作应用超时,以便在指定的时间后读取将被中止.

据我所知,NetworkStream或TcpClient不支持 - 有一个ReceiveTimeout属性,但这似乎只适用于同步等效 - 'Read'.

甚至底层的Socket类似乎也不支持其BeginReceive方法中的超时.

我已经搜索过这个问题,我看到的唯一建议的解决方案是设置另一个后台线程来取消操作,如果它在超时期限内没有完成.这看起来像是一个可怕的黑客.当然有更好的方法吗?

asynchronous networkstream tcpclient beginread beginreceive

15
推荐指数
1
解决办法
1万
查看次数

是否需要关闭NetworkStream和TcpClient,或只关闭TcpClient?

我正在阅读有关TcpClient.Close()的文档并注意到这一点:

调用此方法最终将导致关联的Socket关闭,并且还将关闭用于发送和接收数据的关联NetworkStream(如果已创建).

因此,纠正我,如果我错了,但是这说,如果一个调用Close()TcpClient是,NetworkStream也将被关闭.

那么为什么在代码示例的末尾都会Close()被调用?

networkStream.Close();
tcpClient.Close();
Run Code Online (Sandbox Code Playgroud)

只打电话会一样tcpClient.Close();好吗?

c# dispose networkstream tcpclient

15
推荐指数
1
解决办法
9076
查看次数