我有一个客户端/服务器基础设施.目前,他们使用TcpClient和TcpListener在所有客户端和服务器之间发送接收数据.
我目前所做的是当收到数据时(在它自己的线程上),它被放入一个队列中供另一个线程处理,以便释放套接字,使其准备好并打开以接收新数据.
// Enter the listening loop.
while (true)
{
Debug.WriteLine("Waiting for a connection... ");
// Perform a blocking call to accept requests.
using (client = server.AcceptTcpClient())
{
data = new List<byte>();
// Get a stream object for reading and writing
using (NetworkStream stream = client.GetStream())
{
// Loop to receive all the data sent by the client.
int length;
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0)
{
var copy = new byte[length];
Array.Copy(bytes, 0, copy, 0, length);
data.AddRange(copy); …Run Code Online (Sandbox Code Playgroud) 我有一个服务器和客户端使用TcpListener和设置TcpClient.
我想将一个对象发送到我的服务器应用程序进行处理.
我已经发现了using System.Runtime.Serialization以下文档,但是我不想四处寻找我正在以冗长的方式做这件事.
问题:通过TCP流处理和发送对象的最佳方法是什么?
发送和接收.
这是我的对象的一个例子:
// Create a new house to send
house newHouse = new house();
// Set variables
newHouse.street = "Mill Lane";
newHouse.postcode = "LO1 BT5";
newHouse.house_number = 11;
newHouse.house_id = 1;
newHouse.house_town = "London";
Run Code Online (Sandbox Code Playgroud) 问题是,如果IPAddress.Any作为参数给出,以下代码可以正常工作,但如果使用`IPAddress.IPv6Any则抛出错误.
我收到错误#10057
套接字未连接.
不允许发送或接收数据的请求,因为套接字未连接(当使用sendto在数据报套接字上发送时)没有提供地址.任何其他类型的操作也可能返回此错误 - 例如,如果已重置连接,则setsockopt设置SO_KEEPALIVE.
为什么它不能像IPv6一样工作?我很确定它不是防火墙,因为端口保持不变并且它适用于IPv4(我的防火墙应该传递我的应用程序发出的任何请求).
要简化代码,它是这样的:
听众:
listener = new TcpListener(IPAddress.IPv6Any, portNr);
listener.AllowNatTraversal(true);
listener.Start();
listener.BeginAcceptTcpClient(this.AcceptClient, null);
Run Code Online (Sandbox Code Playgroud)
客户端:
client = new TcpClient();
client.NoDelay = true;
try
{
this.client.Connect(ip, port); //ip = "localhost" when connecting as server
}
catch (Exception ex)
{
FileLogger.LogMessage(ex);
Disconnect();
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试建立TCP连接的"服务器端".
我所做的是我在localhost启动一个监听器,然后作为客户端连接到它(并允许其他人作为客户端加入).
我想要实现的是这个TCP服务器的直接可寻址性,遵循这篇文章:http://blogs.msdn.com/b/ncl/archive/2009/07/27/end-to-end-connectivity -with-NAT遍历-的.aspx
我这样做的原因是我希望人A能够在他们都在NAT路由器后面时连接到B人.
我正在使用通过TCP协议接收文件的应用程序,应用程序处理文件然后通过相同的协议发送它,我接收文件没有问题,我的问题是当我尝试发送文件,因为我需要将文件发送到另一个正在侦听动态端口的应用程序,我用来发送这些文件的代码是:
internal void Send(byte[] buffer)
{
TcpClient _client = null;
try
{
_client = new TcpClient(RemoteIPaddress, Dynamic_port);
if (_client != null)
{
NetworkStream _clienttStream = _client.GetStream();
_clienttStream.Write(buffer, 0, buffer.Length);
_clienttStream.Flush();
_clienttStream.Close();
_clienttStream = null;
}
}
catch
{
if (_client != null)
{
_client.Close();
_client = null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,如何通过TCP协议将文件发送到使用动态端口的远程计算机
根据问题数量,论坛帖子等,BCL中的TcpClient/NetworkStream实现似乎缺乏对取消IO操作的良好支持.随着.NET 4.5中Async方法的增加,这种缺少取消(或者不错的超时支持)使得事情变得更加令人沮丧,因为在执行IO时取消拒绝监视其CancellationToken的任务变得更加复杂(几乎不可能) .
我已经看到许多实现启动其他线程来监视网络操作并在事情看起来出错时关闭底层流.在我们试图通过使用异步操作来节省这些资源的世界中,这感觉非常脏.
任何人都可以指导我处理有效取消/超时网络IO操作或实际工作的强大第三方实施的指导方向吗?
我正在创建一个C#库,使用Airplay协议将照片和视频发送到我的Apple TV(特别是与第3代一起使用,但希望这对此无关紧要).
根据此规范,Airplay的所有命令都是端口70上的HTTP:http: //nto.github.com/AirPlay.html
我已成功地在Apple TV上播放照片和视频,但无论我做什么,AppleTV都只播放30秒的视频.看起来我的C#客户端发出播放命令就是在30秒时断开连接,这导致AppleTV结束播放会话.
我认为这个的原因:
我很确定客户端请求需要在视频的"播放"过程中保持连接,据我所知,我已将其编码为此.我真的在我的智慧结束.我已经尝试了我能想到的所有内容,包括作为HttpWebRequest和原始TcpClient(两者都工作但都超时)执行请求,将接收/发送超时设置为疯狂数字,并循环读取Tcp流确保有"活动".
好像AppleTV期待我发送"嘿,继续播放"的消息,但我还没有从网上的任何来源看到类似的东西.我希望这只是一些愚蠢的东西,我不是基于我缺乏Http/Tcp知识.
这是我的代码:
Uri url = "http://somevideo.com/video.mov";
float startPosition = 0;
TcpClient tcpClient = new TcpClient("192.168.1.20",7000);
tcpClient.ReceiveTimeout = 100000;
tcpClient.SendTimeout = 100000;
//get the client stream to read data from.
NetworkStream clientStream = tcpClient.GetStream();
string body =
"Content-Location: " + url + "\n" +
"Start-Position: " + startPosition + "\n";
string request = "POST /play HTTP/1.1\n" +
"User-Agent: MediaControl/1.0\n" +
"Content-Type: text/parameters\n" +
"Content-Length: " …Run Code Online (Sandbox Code Playgroud) 我已经为我的服务器编写了这段代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
private static bool terminate;
public static bool Terminate
{
get { return terminate; }
}
private static int clientNumber = 0;
private static TcpListener tcpListener;
static void Main(string[] args)
{
StartServer();
Console.Read();
}
private static void StartServer()
{
try
{
Console.WriteLine("Server starting...");
tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8000);
terminate = false;
tcpListener.Start();
tcpListener.BeginAcceptTcpClient(ConnectionHandler, null);
Console.ReadLine();
} …Run Code Online (Sandbox Code Playgroud) 通过超时取消TcpClient ReadAsync操作并在.NET 4.5中捕获此超时事件的正确方法是什么?
TcpClient.ReadTimeout似乎应用于同步只读.
更新:
Tried tro应用此处描述的方法取消异步操作
var buffer = new byte[4096];
CancellationTokenSource cts = new CancellationTokenSource(5000);
int amountRead = await tcpClientStream.ReadAsync(buffer, 0, 4096, cts.Token);
Run Code Online (Sandbox Code Playgroud)
但它永远不会超时取消.有什么问题吗?
出于安全原因,我想阅读证书详细信息(例如到期日期或CN).
通常,网络类中有一些属性可用于检查证书.这在WP8实现中缺失.
此外,我尝试创建一个SslStream,但也无法获得任何证书详细信息,如.net 4.5上的RemoteCertificate.
var sslStream = new SslStream(new NetworkStream(e.ConnectSocket));
Run Code Online (Sandbox Code Playgroud)
SslStream缺少与安全相关的所有内容.所以看起来BountyCastle和其他库也无法获得证书,因为底层框架不支持它.
所以我的问题是:
关心霍尔格
ssl network-programming bouncycastle tcpclient windows-phone-8
我使用围绕构建的网络协议TcpClient,BinaryReader用于从底层读取字节NetworkStream(相反,BinaryWriter用于写入)。
该协议以UTF-8编码传输字符串,并正在调用reader.ReadString()以从流中读取它们(writer.Write(someStr)用于写入)。
是否有一种简单的方法来确定从NetworkStream读取(或写入)的字节数,而不必跳过箍来计算所传输字符串的实际字节长度?
请注意,BinaryWriter.Write()在字符串的实际字节之前写入一个7位编码的整数,这会使任何手动计算变得更加复杂。
另请注意,NetworkStream该Position属性不支持该属性,因为它抱怨无法使用Seek。
此外,我想避免将必须复制/扫描数据的中介引入到读/写过程中,以免影响整个系统的性能。
是否有一种简单,高级的方法来计数通过网络接口传递的字节,而无需手动考虑字符串的编码和长度?
tcpclient ×10
c# ×8
tcplistener ×4
tcp ×2
.net ×1
apple-tv ×1
asyncsocket ×1
binaryreader ×1
bouncycastle ×1
c#-4.0 ×1
ipv6 ×1
networking ×1
sockets ×1
ssl ×1
timeout ×1