我编写了一个程序,使用Apple的流编程指南中概述的NSStream协议连接到给定IP上的服务器.数据的连接和传输完美无缺,但是如果用户指定了错误的IP并且程序试图打开流,则会导致程序无响应.
从我读过的,handleEvent方法检测流错误,但是当我检查eventCode == NSStreamEventErrorOccurred的条件时,似乎没有任何事情发生.我的连接代码如下:
NSString *hostString = ipField.text;
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)hostString, 10001, &readStream, &writeStream);
inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
Run Code Online (Sandbox Code Playgroud)
如果无法建立连接,是否可以指定超时值或允许按钮触发流的关闭?
我目前正在编写一个通过串行连接与集成伺服器通信的应用程序.
电机以高达1000次/秒的速率发送位置数据.我想要实现的是能够格式化返回的数据(通过剥离空格,新行等)并解析它以从接收的字符串中提取相关数据.
目前,我有数据接收事件处理程序读取数据,使用一系列string.replace方法调用格式化它,并将其附加到充当缓冲区的字符串.然后,使用线程,我不断检查缓冲区,因为它填充特定的分隔符(在我的情况下为"\ r"),表示来自电机的一条消息的结束,然后从缓冲区中删除该消息并将其打印到富有文本域.
这种方法存在两个问题.一个是因为电机以如此高的速率传输位置数据,所以缓冲器填充的速度比线程可以处理的数据快.因此,当我向电机发送命令时,它会立即动作,但响应会延迟几秒钟,因为必须首先处理缓冲区中的所有前面的数据.其次,让两个线程运行一个实现while(true)结构的方法意味着处理器利用率急剧上升,并且在几秒钟内,pc中的风扇最大.
有更好的方法来处理数据吗?
这是我的事件处理程序代码:
//data recieved event handler
private void dataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string tmp;
tmp = sp.ReadExisting();
//cut out any unnecessary characters
tmp = tmp.Replace("\n", "");
tmp = tmp.Replace(",", "\r");
tmp = tmp.Replace(" ", "");
lock (this)
{
//put all received data into the read buffer
readBuffer += tmp;
}
}
Run Code Online (Sandbox Code Playgroud)
这是线程执行的方法:
private void parseBuffer()
{
while (true)
{
//obtain lock, parse one message from buffer
lock (this)
{
if (readBuffer.IndexOf("\r") > 0)
{ …Run Code Online (Sandbox Code Playgroud) 我正在尝试在Visual Studio 2010中编写ac#程序,它通过串行连接与微控制器通信.我可以很好地读取和写入端口,我只是不确定如何让send方法等待,直到执行前收到上一个send命令的所有数据.我已经实现了数据接收事件处理程序,以便确定何时在串行端口上接收到所请求的适当数据量.我只需要知道如何导致告诉send方法端口是空闲的.
我曾计划使用互斥锁,但我认为问题不在于多线程.相同的线程一个接一个地在串行端口上发送字符串,并且响应第一个请求而接收的数据与第二个请求冲突.
此外,如果通信由一个线程完成,那么该线程是否会导致数据接收事件处理程序不执行?
(两种方法属于同一类)
我的发送数据方法:
//method for sending data
public void send(String s)
{
sp.Write(s + "\r");
}
Run Code Online (Sandbox Code Playgroud)
我的数据收到事件处理程序
//data received event handler
private void dataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string tmp;
tmp = sp.ReadExisting();
//put all received data into the read buffer
readBuffer += tmp;
//add various flag checks to determine end of transmission
if (firmwareFlag)
{
if (readBuffer.EndsWith("\n"))
{
firmwareFlag = false;
//trigger event to tell object owner data is ready
dataReady(this, new CustomEventArgs(readBuffer, "firmware"));
readBuffer …Run Code Online (Sandbox Code Playgroud) 我已经实现了一个模拟串行端口的DataReceived事件的系统,从而使用BeginRead()方法触发从TCPClient对象的NetworkStream读取数据,如下所示:
TcpClient server = new TcpClient();
server.Connect(IPAddress.Parse(ip), 10001);
server.GetStream().BeginRead(buffer, 0, buffer.Length, new AsyncCallback(DataReceived), server.GetStream());
Run Code Online (Sandbox Code Playgroud)
从另一个线程调用以下方法:
private void DataReceived(IAsyncResult result)
{
res = result;
server.GetStream().EndRead(result);
//append received data to the string buffer
stringBuffer += System.Text.ASCIIEncoding.ASCII.GetString(buffer);
//clear the byte array
Array.Clear(buffer, 0, buffer.Length);
//trigger the parser
waitHandle.Set();
server.GetStream().BeginRead(buffer, 0, buffer.Length, new AsyncCallback(DataReceived), buffer);
}
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常.我可以毫无问题地向网络上的设备发送和接收数据.但是,当我尝试使用以下方法断开连接时,程序崩溃:
public override void disconnect()
{
server.Close();
}
Run Code Online (Sandbox Code Playgroud)
它会引发以下错误:
A first chance exception of type 'System.ObjectDisposedException' occurred in System.dll
Run Code Online (Sandbox Code Playgroud)
我也尝试过如下实现disconnect方法:
server.GetStream().Close();
Run Code Online (Sandbox Code Playgroud)
但这会导致以下错误:
A first chance exception of type …Run Code Online (Sandbox Code Playgroud) 我目前正在构建一个多文档界面应用程序,但是当通过x按钮关闭子窗体时我遇到了问题.当窗体关闭时,再次显示它的唯一方法是创建该特定窗体的新实例,这意味着前一个窗体中包含的所有数据都将丢失.
我试图将表单关闭事件设置为简单地隐藏表单,但是当用户关闭主父表单时,应用程序不会退出.
有没有解决的办法?
这是我目前用于我的子表单'表单结束事件的代码:
private void ParameterForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason != CloseReason.FormOwnerClosing)
{
this.Hide();
e.Cancel = true;
}
}
Run Code Online (Sandbox Code Playgroud)
使用此代码,必须单击主窗体的x按钮两次,一次关闭子窗体,一次关闭主窗体.
我在将位置坐标传送到我在网络上连接的一组电机时遇到问题.我可以发送一个字符串就好了,并从电机接收文本,但我似乎无法发送一个int值.
使用NSlog我已经确定我发送的实际值是正确的,但我怀疑我通过输出流发送它的方法是错误的.有任何想法吗?
我发送64位int值的代码:
uint64_t rawInt = m1;
rawInt <<= 16;
rawInt |= m2;
NSData *buffer = [NSData dataWithBytes: &rawInt length:8];
[outputStream write: [buffer bytes] maxLength:[buffer length]];
Run Code Online (Sandbox Code Playgroud) c# ×4
iphone ×2
serial-port ×2
.net ×1
asynchronous ×1
cocoa ×1
connection ×1
int ×1
mdi ×1
networking ×1
nsstream ×1
parsing ×1
stream ×1
winforms ×1