我正在编写一个程序,它监听传入的TcpClient并在数据到达时处理数据.该Listen()方法在组件内的单独线程上运行,因此它需要是线程安全的.如果我在一个声明中break出了do while循环lock(),锁定会被释放吗?如果没有,我该如何做到这一点?
谢谢!
(关于异步TCP套接字主题的任何其他建议也是受欢迎的.)
private void Listen()
{
do
{
lock (_clientLock)
{
if (!_client.Connected) break;
lock (_stateLock)
{
if (!_listening) break;
if (_client.GetStream().DataAvailable) HandleData();
}
}
Thread.Sleep(0);
} while (true);
}
Run Code Online (Sandbox Code Playgroud) 我正在开发一个需要TCP连接到TCP服务器的Android应用程序(以Node.js编写)
我的Android TCP客户端正在工作,可以来回发送消息.
我的特定问题是:
我在AsyncTask中有我的套接字连接,如下所示:
@Override
protected Void doInBackground(Void... params) {
try {
Log.d("TCP_MESSAGE", "Connecting...");
socket = new Socket(MY_LOCAL_IP, 8080);
dataOutput = new DataOutputStream(socket.getOutputStream());
inputstream = new InputStreamReader(socket.getInputStream());
input = new BufferedReader(inputstream);
while (!canceled) {
String message = input.readLine();
handleMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
我在AsyncTask中连接的原因是因为我使用的是android 4.0并且不允许在常规线程中使用网络代码.
我试图读取通过机器的缓冲区中存在的所有数据,TCP/IP但我不知道为什么我没有得到所有数据,一些数据正在错过.这是我正在使用的代码..
using (NetworkStream stream = client.GetStream())
{
byte[] data = new byte[1024];
int numBytesRead = stream.Read(data, 0, data.Length);
if (numBytesRead > 0)
{
string str= Encoding.ASCII.GetString(data, 0, numBytesRead);
}
}
Run Code Online (Sandbox Code Playgroud)
请告诉我我缺少什么来从机器获取所有数据.提前致谢..
这是另一个C#/.NET问题仅基于好奇而不仅仅是一个迫切需要 ......
如果你有一个Socket实例,并且想要将它包装在更高级别的TcpClient类中,那可能吗?你会怎么做?
相反,如果你有一个实例TcpClient,是否有可能获得底层Socket?
因此,似乎阻塞的Read()可以在接收到发送给它的所有数据之前返回.反过来,我们用一个循环来包装Read(),该循环由相关流中的DataAvailable值控制.问题是你可以在这个while循环中接收更多数据,但是没有幕后处理让系统知道这一点.我在网上找到的大多数解决方案都不适用于我.
我最后做的是作为循环的最后一步,在从流中读取每个块之后,我做了一个简单的Thread.Sleep(1).这似乎给系统提供了更新的时间,而且我没有得到准确的结果,但这对于解决方案来说似乎有点苛刻且有点"间接".
下面是我正在处理的情况列表:IIS应用程序和独立应用程序之间的单个TCP连接,都是用C#编写的,用于发送/接收通信.它发送请求然后等待响应.此请求由HTTP请求启动,但我没有从HTTP请求中读取数据这个问题,事后是这样.
以下是处理传入连接的基本代码
protected void OnClientCommunication(TcpClient oClient)
{
NetworkStream stream = oClient.GetStream();
MemoryStream msIn = new MemoryStream();
byte[] aMessage = new byte[4096];
int iBytesRead = 0;
while ( stream.DataAvailable )
{
int iRead = stream.Read(aMessage, 0, aMessage.Length);
iBytesRead += iRead;
msIn.Write(aMessage, 0, iRead);
Thread.Sleep(1);
}
MemoryStream msOut = new MemoryStream();
// .. Do some processing adding data to the msOut stream
msOut.WriteTo(stream);
stream.Flush();
oClient.Close();
}
Run Code Online (Sandbox Code Playgroud)
所有反馈都欢迎提供更好的解决方案,或者只是赞一下需要给Sleep(1)一个允许在检查DataAvailable值之前正确更新的东西.
猜猜我希望2年后这个问题的答案不是如何仍然是:)
我有两个简单的应用程序:
等待特定tcp端口以供客户端连接的服务器应用程序.然后听他说的话,发回一些反馈并断开那个客户端.
一个表单应用程序连接到服务器应用程序,然后说出一些内容,然后等待反馈并断开与服务器的连接,然后在表单中显示反馈.
虽然服务器应用程序似乎行为正常(我已经使用Telnet对其进行了测试,并且我看到反馈并且我看到反馈后直接发生了断开连接),但表单应用程序似乎并未发现与服务器的断开连接.(即使在服务器断开连接后,TcpClient.Connected似乎也保持正常)
我的问题是:为什么TcpClient.Connected保持正确,我怎么知道服务器是否/何时断开连接?
这是我的完整代码:
表格申请:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace Sender
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void sendButton_Click(object sender, EventArgs e)
{
TcpClient tcpClient = new TcpClient();
tcpClient.Connect(IPAddress.Parse("127.0.0.1"), 81);
responseLabel.Text = "waiting for response...";
responseLabel.Invalidate();
// write request
NetworkStream networkStream = tcpClient.GetStream();
byte[] buffer = (new ASCIIEncoding()).GetBytes("Hello World! ");
networkStream.Write(buffer, 0, buffer.Length);
networkStream.Flush();
// read response
Thread readThread = …Run Code Online (Sandbox Code Playgroud) 由于Heartbleed,我们的网关服务器已更新,此问题出现了.
由于POODLE,不再支持SSLv3.
客户端应用程序(.NET 2.0)位于Windows 7(或8)框中.服务器在网关服务器后面的DMZ内运行.请注意,我发现.NET 4.0+上不再存在这个问题 - 但是由于遗留代码,我没有更新的奢侈.
Gateway Server是一个传递框,运行带有SSL的Apache HTTP Server.它的位置在DMZ之外,用于访问DMZ内部的服务器.在Gateway服务器上运行的软件版本是Apache/2.2.25(Win32),mod_jk/1.2.39,mod_ssl/2.2.25,OpenSSL/1.0.1g
以下是客户端应用程序上使用的代码(添加了大量的日志记录)...注意,'serverName'通常包含诸如" https://some.url.com "之类的值.
private bool ConnectAndAuthenicate(string serverName, out TcpClient client, out SslStream sslStream)
{
client = null;
sslStream = null;
try
{
client = new TcpClient(serverName, 443); // Create a TCP/IP client; ctor attempts connection
Log("ConnectAndAuthenicate: Client CONNECTED"));
sslStream = new SslStream(client.GetStream(), false, ValidateServerCertificate, null);
Log("ConnectAndAuthenicate: SSL Stream CREATED"));
}
catch (Exception x)
{
Log("ConnectAndAuthenicate: EXCEPTION >> CONNECTING to server: …Run Code Online (Sandbox Code Playgroud) 编程TCP服务器时,我想设置从客户端读取请求的超时时间:
var tcpClient = tcpListener.AcceptTcpClient();
var networkStream = tcpListener.GetStream();
tcpClient.ReceiveTimeout = 10000;
networkStream.ReadTimeout = 10000;
Run Code Online (Sandbox Code Playgroud)
见最后两行.我应该选择哪一个?它们在有效性方面是否相同,或者它们在哪些方面有所不同?
我正在研究一种客户端/服务器关系,它意味着在不确定的时间内来回推送数据.
我试图克服的问题是在客户端,因为我无法找到一种方法来检测断开连接.
我在其他人的解决方案中采取了几个传递,从捕获IO异常到轮询所有三个SelectMode上的套接字.我还尝试使用轮询的组合,并检查套接字的"可用"字段.
// Something like this
Boolean IsConnected()
{
try
{
bool part1 = this.Connection.Client.Poll(1000, SelectMode.SelectRead);
bool part2 = (this.Connection.Client.Available == 0);
if (part1 & part2)
{
// Never Occurs
//connection is closed
return false;
}
return true;
}
catch( IOException e )
{
// Never Occurs Either
}
}
Run Code Online (Sandbox Code Playgroud)
在服务器端,尝试向客户端写入"空"字符(\ 0)会强制执行IO异常,服务器可以检测到客户端已断开连接(非常简单).
在客户端,相同的操作不会产生异常.
// Something like this
Boolean IsConnected( )
{
try
{
this.WriteHandle.WriteLine("\0");
this.WriteHandle.Flush();
return true;
}
catch( IOException e )
{
// Never occurs
this.OnClosed("Yo socket sux"); …Run Code Online (Sandbox Code Playgroud) 我试图了解NetworkStream.EndRead()的MSDN示例.有些部分我不明白.
所以这是示例(从MSDN复制):
// Example of EndRead, DataAvailable and BeginRead.
public static void myReadCallBack(IAsyncResult ar ){
NetworkStream myNetworkStream = (NetworkStream)ar.AsyncState;
byte[] myReadBuffer = new byte[1024];
String myCompleteMessage = "";
int numberOfBytesRead;
numberOfBytesRead = myNetworkStream.EndRead(ar);
myCompleteMessage =
String.Concat(myCompleteMessage, Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
// message received may be larger than buffer size so loop through until you have it all.
while(myNetworkStream.DataAvailable){
myNetworkStream.BeginRead(myReadBuffer, 0, myReadBuffer.Length,
new AsyncCallback(NetworkStream_ASync_Send_Receive.myReadCallBack),
myNetworkStream);
}
// Print out the received message to the console.
Console.WriteLine("You received the following message …Run Code Online (Sandbox Code Playgroud) tcpclient ×10
c# ×8
tcp ×3
.net ×2
sockets ×2
timeout ×2
android ×1
asynchronous ×1
c#-2.0 ×1
disconnect ×1
ioexception ×1
locking ×1
sslstream ×1
stream ×1
streamwriter ×1
system.net ×1
tcp-ip ×1