我尝试使用TcpClient发送/接收数据.我做了两个实验,发现了一些有趣的东西
我在日本的服务器和英国的TcpClient中设置了TcpListener.我一直向TcpListener发送500个字节,当TcpListener将10KB发送回TcpClient时.我在每个实验中保持这个发送/接收循环500次.
实验1:
在每个发送/接收循环中,我创建一个全新的TcpClient(创建之前的时间滴答)并发送/接收
实验2:
对于所有循环,我只有一个TcpClient,它保持与TcpListener的连接并执行500次发送/接收.
结果:
一个循环的时间成本的平均值:
E1:1.8秒,E2:0.49秒.
我很惊讶这个结果.所以保持连接不断的发送/接收可以节省大量的时间??? 近2/3的时间.
这是真的???
谢谢
==== ====新
@Jon Skeet,@ dbemerlin,谢谢你的回复.我猜测Tcp握手需要一些时间工具.
所以我做了实验3.
我将HttpListener设置为服务器并使用WebClient进行发送/接收,数据大小完全相同.每次我使用新的WebClient在英国和日本之间发送/接收.
结果是0.86(平均来自500次循环,即发送/接收).
我假设WebClient/HttpLisener本身就是Tcp,对吧?在我的实验中,它们如何比原始TcpClient/TcpListener更快?
再次感谢
我正在使用System.Net.Sockets.TcpClient类,但每当我通过网络发送自定义数据包时,我看到我的wireshark捕获的校验和错误.我该如何解决?
我正在编写一个小型(C#)客户端应用程序,该应用程序使用TCP / IP连接将数据发送到远程服务器。我正在使用标准的.Net TcpClient对象,并且由于我要定期向服务器提交数据包,因此希望从客户端打开连接。但是,服务器可能会关闭连接,在这种情况下,我需要在发送下一个数据包之前重新连接。
使用Wireshark,当服务器终止连接时,我只能看到以下对话框:
server >>> FIN, ACK
ACK <<< client
我所没有看到的是我的客户拥有自己的FIN响应,以完成连接关闭。结果是我的客户端程序仅在发送下一个数据包后才发现连接已断开。
有什么方法可以设置TcpClient或它的基础Socket以完成断开连接,并提供一些反馈,以便我的客户端代码在发送下一个数据包之前知道重新连接?
为了回应以下评论而添加:我的发送代码非常简单-维护TcpClient和NetworkStream成员变量的对象具有一个成员函数,该成员函数包含(基本上)以下内容:
bool sent = false;
byte[] buffer = Encoding.UTF8.GetBytes(dataString);
while (!sent)
{
try
{
m_outStream.Write(buffer, 0, buffer.Length);
sent = true;
}
catch (Exception ex)
{
if (m_outStream != null) { m_outStream.Dispose(); }
m_client = new TcpClient(AddressFamily.InterNetwork);
m_client.Connect(ipAddress, ipPort);
m_outStream = m_client.GetStream();
}
}
Run Code Online (Sandbox Code Playgroud)
初始化了m_client和m_outStream以后,每次只需执行一次传递。然后,使用Wireshark,我可以看到服务器发送了带有标志的数据包,FIN, ACK客户端对此进行了响应ACK。
下次调用函数时,数据将通过发送出去PSH, ACK,服务器将以响应RST, ACK但不读取传入的数据。客户端不会引发异常。
然后,我第二次调用函数,并引发异常,导致重新启动连接。
出于构造速率限制器的目的,我需要能够区分通过同一网关路由的不同用户.因此,如果我有100个具有相同IP地址的客户端,我想将它们与远程网关/主机/路由器上的相关端口区分开来.
我可以轻松获得IP:
string clientIPAddress = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address.ToString();
Run Code Online (Sandbox Code Playgroud)
是否有类似的方法来获取客户端的远程端口号?谢谢.
为了让我的脚趾在网络编程的水中,我写了一个小的控制台应用程序将png文件发送到服务器(另一个控制台应用程序).服务器写入的文件略大于源png文件.它不会打开.
客户端应用程序的代码是:
private static void SendFile()
{
using (TcpClient tcpClient = new TcpClient("localhost", 6576))
{
using (NetworkStream networkStream = tcpClient.GetStream())
{
//FileStream fileStream = File.Open(@"E:\carry on baggage.PNG", FileMode.Open);
byte[] dataToSend = File.ReadAllBytes(@"E:\carry on baggage.PNG");
networkStream.Write(dataToSend, 0, dataToSend.Length);
networkStream.Flush();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Server应用程序的代码是:
private static void Main(string[] args)
{
Thread thread = new Thread(new ThreadStart(Listen));
thread.Start();
Console.WriteLine("Listening...");
Console.ReadLine();
}
private static void Listen()
{
IPAddress localAddress = IPAddress.Parse("127.0.0.1");
int port = 6576;
TcpListener tcpListener = new TcpListener(localAddress, port);
tcpListener.Start();
using (TcpClient …Run Code Online (Sandbox Code Playgroud) 我正在尝试通过TCP流向页面发送GET请求.
这是我的代码的样子:
public class SocketLevelWebClient
{
public string SendWebRequest(string url, string request)
{
using(TcpClient tc = new TcpClient())
{
tc.Connect(url, 80);
using (NetworkStream ns = tc.GetStream())
{
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(ns))
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(ns))
{
sw.Write(request);
sw.Flush();
return sr.ReadToEnd();
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请求本身:
SocketLevelWebClient wc = new SocketLevelWebClient();
var r=wc.SendWebRequest("www.youtube.com",@"GET http://www.youtube.com/ HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*
Accept-Language: en-US
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; …Run Code Online (Sandbox Code Playgroud) 我甚至不好意思问这个问题,但经过谷歌的一次精疲力竭的搜索(开始有MSDN ......)后,我决定发布它:
刚刚开始学习客户端 - 服务器编程(使用C#),并尝试使用tcpClient编写我的第一个代码.我正在写服务器端和客户端.这是我的问题:不断,客户端将一个String发送到服务器,然后服务器将一个String发送回客户端,依此类推.服务器不能连续发送2个字符串吗?他必须等待客户的回应?这是客户端服务器的原理吗?
再一次,抱歉这个糟糕的问题.谢谢...
<>我会尝试发布一些代码(很长的代码......).我试图削减redandent部分,所以希望代码有任何意义...(我用//*********标记主要的problam)
public class MServer2
{
Dictionary<String, String> nameAndPass = new Dictionary<String, String>();
Dictionary<String, List<String> > nameAndMail = new Dictionary<String, List<String>>();
public static void Main()
{
new MServer2();
}
public MServer2()
{
TcpListener server = new TcpListener(8500);
try
{
server.Start();
Console.WriteLine("started " + server);
while (true)
{
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("connection accepted " + client);
new Server1(client, nameAndPass, nameAndMail);
}
}
catch (Exception e)
{
Console.WriteLine("exception" + e);
}
finally
{
server.Stop();
} …Run Code Online (Sandbox Code Playgroud) 与我的其他问题相关,除了现在我尝试异步希望它能解决问题.它没有.
我正在尝试创建一个简单的SOCKS5服务器.我将浏览器(firefox)设置为使用此程序作为SOCKS5.这个想法是一个程序连接到代理服务器,为它提供所需的信息,服务器只是简单地从一个连接读取/写入数据到另一个连接.这个只是这样做,不记录也不过滤任何东西.这很简单,但由于CPU问题以及在点击几页后连接到站点需要几秒钟的事实使其完全无法使用.这怎么会占用这么多CPU?为什么连接到网站需要很长时间?异步和同步都受此影响
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Timers;
using System.IO;
using System.Net;
using System.Threading;
namespace ProxyTest
{
class Program
{
static ManualResetEvent tcpClientConnected =new ManualResetEvent(false);
static void Main(string[] args)
{
var s2 = new TcpListener(9998);
s2.Start();
Task.Run(() =>
{
while (true)
{
tcpClientConnected.Reset();
s2.BeginAcceptTcpClient(Blah, s2);
tcpClientConnected.WaitOne();
}
});
while (true)
System.Threading.Thread.Sleep(10000000);
}
static void Blah(IAsyncResult ar)
{
try
{
Console.WriteLine("Connection");
TcpListener listener = (TcpListener)ar.AsyncState;
using (var socketin = listener.EndAcceptTcpClient(ar))
{ …Run Code Online (Sandbox Code Playgroud) 有人可以解释他们的分歧吗?它们是否相同且工作方式相同?哪一个比其他组件好?
我在客户端和服务器上都有一个单独的线程,它正在向/从套接字读取/写入数据.
我正在使用同步TcpClient im(如文档中所建议):https: //msdn.microsoft.com/cs-cz/library/system.net.sockets.tcpclient%28v=vs.110%29.aspx
当连接关闭时.Read()/.Write()抛出异常.是否意味着当.Write()方法没有将数据正确传递给另一方时,或者我是否需要实现自定义ACK逻辑?
我阅读了Socket和TcpClient类的文档,但没有一个描述这种情况.