我在iPhone上使用AsyncSocket与服务器通信.AsyncSocket基于运行循环,但我的应用程序基于线程.这意味着,我启动一个新线程来写入数据,并等待直到在同一个线程上收到响应.但我不能直接从另一个线程调用AsyncSocket的方法,我必须使用:
[self performSelectorOnMainThread:@selector(writeSomeData:) withObject:dataToWrite waitUntilDone:YES];
Run Code Online (Sandbox Code Playgroud)
它确实有效,但我无法通过这种方式调用我的方法"writeSomeData:",因为performSelectorOnMainThread不返回任何内容.
方法writeSomeData:做这样的事情:
-(NSData *)writeData:(NSData *)dataToWrite {
dataReceived = nil; // AsyncSocket writes data to this variable
[asyncSocket writeData:dataToWrite withTimeout:-1 tag:0];
[asyncSocket readDataToData:[@"<EOF" dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
int counter = 0;
while (dataReceived == nil && counter < 5) {
// runLoop is [NSRunLoop currentRunloop]
[runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.3]];
++counter;
}
return [dataReceived copy];
}
Run Code Online (Sandbox Code Playgroud)
我可以通过访问类变量"dataReceived"获得响应,但此时内容已更改.
任何人都可以告诉我如何在不同的线程上使用AsyncSocket(或者一般来说,如何处理基于运行循环的类),这样如果我调用该类的方法,它会一直阻塞,直到执行该方法并收到响应?
谢谢.
这实际上是一个实现问题,所以我觉得最好从我的具体案例开始.
我有一个C#服务器,它从移动客户端异步侦听TCP连接.当移动客户端连接新线程启动时,客户端发送一些(通常<100字节)文本消息并接收相似大小的文本消息.服务器响应后,它会关闭连接并结束线程.
当前的基本用法是用户登录,有时最多5分钟检查一些内容,发送少量消息,从而快速连续地在服务器上创建新线程,并且几小时后它们仅断开连接.此外,每个用户都有自己的PC上运行的服务器,因此大多数服务器在任何给定时间只能连接一个客户端,在RARE情况下只有两个.
现在我遇到了以下错误,现有连接被远程主机强行关闭,它让我思考,我做错了吗?
所以我的问题:
回答这里的一些问题:
public void StartListening()
{
//Data buffer for incoming data.
byte[] bytes = new Byte[1024];
//Establish the local endpoint for the socket.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, Port);
//Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
listener.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.DontLinger,1);
listener.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReuseAddress,1);
//Bind the socket to the local endpoint and listen …Run Code Online (Sandbox Code Playgroud) 我在我的iPhone应用程序中使用AsyncUDPSocket第三方库,并且在大多数情况下它运行良好.我有一个单独的实例AsyncUDPSocket,我用于我的所有网络流量.我的应用程序在后台注册了位置跟踪,并在后台运行时唤醒并通过网络发送位置更新数据包.这一切都在背景,前景,手机锁定或解锁状态下运行,除非我执行以下操作:
SIGPIPE/ EPIPE错误和应用程序崩溃.我认为解决这个问题的最佳方法是在应用程序退出并且未启用后台跟踪时关闭并释放套接字,但是当我尝试[socket close]或者[socket release]在上面时AsyncUDPSocket,我会遇到各种EXC_BAD_ACCESS错误.我已经向开发团队提交了一个错误,但是想知道这里是否有人可以提供一些关于如何SIGPIPE完全避免错误或其他方法来保持套接字存活而不释放它的想法.谢谢.
根据问题数量,论坛帖子等,BCL中的TcpClient/NetworkStream实现似乎缺乏对取消IO操作的良好支持.随着.NET 4.5中Async方法的增加,这种缺少取消(或者不错的超时支持)使得事情变得更加令人沮丧,因为在执行IO时取消拒绝监视其CancellationToken的任务变得更加复杂(几乎不可能) .
我已经看到许多实现启动其他线程来监视网络操作并在事情看起来出错时关闭底层流.在我们试图通过使用异步操作来节省这些资源的世界中,这感觉非常脏.
任何人都可以指导我处理有效取消/超时网络IO操作或实际工作的强大第三方实施的指导方向吗?
我一直在做一个私人项目,在那里我想学习如何在Windows手机上编程,在某一点上我开始摆弄插座和相机,一个好主意想到了视频输入(愚蠢我甚至尝试).
但现在我在这里,我有一些很好的东西,它就像一个魅力,但Lumia 800不能足够快地通过for循环.它发送一个帧,每个让我们说7-8秒,我觉得很奇怪,它应该足够强大.感觉和看起来像在没有色情片的56k调制解调器上观看色情片.
我还意识到一帧是317000像素,每帧总共大约1MB我也发送xy坐标,所以我的每帧占用2.3MB,仍然以不同的方式解决这个问题以保持低位.所以我猜我需要做圆顶魔法才能使位置和像素值都达到可接受的大小.因为atm我会以一个可接受的速度获得它,它需要至少60MB/s来获得30fps之类的东西,但那是另一天的问题.
//How many pixels to send per burst (1000 seems to be the best)
const int PixelPerSend = 1000;
int bSize = 7 * PixelPerSend;
//Comunication thread UDP feed
private void EthernetComUDP() //Runs in own thread
{
//Connect to Server
clientUDP = new SocketClientUDP();
int[] ImageContent = new int[(int)cam.PreviewResolution.Height * (int)cam.PreviewResolution.Width];
byte[] PacketContent = new byte[bSize];
string Pixel,l;
while (SendingData)
{
cam.GetPreviewBufferArgb32(ImageContent);
int x = 1, y = 1, SenderCount = 0;
//In dire need of a …Run Code Online (Sandbox Code Playgroud) 我正在尝试为我的项目实现异步套接字.这是代码
public void Start(int listeningPort)
{
var ipHostInfo = Dns.Resolve(Dns.GetHostName());
var ipAddress = ipHostInfo.AddressList[0];
var localEndPoint = new IPEndPoint(ipAddress, listeningPort);
_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_listener.Bind(localEndPoint);
_listener.Listen(3000);
Started = true;
Task.Factory.StartNew(() =>
{
while (Started)
{
allDone.Reset();
_listener.BeginAccept(AcceptCallback, _listener);
allDone.WaitOne();
}
});
}
public void Stop()
{
Started = false;
_listener.Shutdown(SocketShutdown.Both); //<-- throws SocketException
_listener.Close(2000);
_listener = null;
}
public void Kick(IClient client)
{
try
{
Clients.Remove(client);
client.Socket.Shutdown(SocketShutdown.Both);
client.Socket.Close();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
private void …Run Code Online (Sandbox Code Playgroud) 我注意到今天,我正在开发的一个应用程序在内存中严重增长.所以我做了一个Visual Studio内存配置文件,我发现了以下结果:
Function Name Inclusive Allocations Exclusive Allocations Inclusive Bytes Exclusive Bytes
System.Net.Sockets.Socket.BeginSend(uint8[],int32,int32,valuetype System.Net.Sockets.SocketFlags,valuetype System.Net.Sockets.SocketError&,class System.AsyncCallback,object) 3 192 569 3 192 561 635 307 885 635 307 621
Run Code Online (Sandbox Code Playgroud)
这是在〜600Meg的内存使用量之上
这对我来说似乎不对,我不确定为什么会这样?
这是我的发送功能:
private void SendSignal(Byte[] signal)
{
if (state.WorkSocket.Connected)
{
try
{
state.WorkSocket.BeginSend(signal, 0, signal.Length, 0, new AsyncCallback(SendCallback), state.WorkSocket);
}
catch (Exception e)
{
log.Error("Transmission Failier for ip: " + state.WorkSocket.AddressFamily , e);
}
}
else
{
CloseConnection();
}
}
Run Code Online (Sandbox Code Playgroud)
应用程序阻塞并发QUEUE并发送消息,当它成功出列消息时,它会循环遍历所有已注册的(客户端)并将此消息发送给它们.
我是否正确使用了开始发送?
我有一件事是,它是异步的,我的程序可能循环遍历整个队列并将其全部卸载到异步系统缓冲区吗?
{编辑}
private void SendCallback(IAsyncResult asyncResult)
{
try
{ …Run Code Online (Sandbox Code Playgroud) 我知道这个话题有时已经被问到了,并且我已经阅读了几乎所有的主题和评论,但是仍然找不到我的问题的答案。
我正在一个高性能的网络库中工作,该库必须具有TCP服务器和客户端,必须能够接受30000多个连接,并且吞吐量必须尽可能高。
我非常清楚我必须使用async方法,并且已经实现了我发现并测试过的所有解决方案。
在我的基准测试中,仅使用了最少的代码来避免范围内的任何开销,我使用了性能分析来最大程度地减少CPU负载,没有更多的空间可以进行简单的优化,在接收套接字上,总是读取,计数和丢弃缓冲区数据以避免套接字缓冲区完全填满。
这种情况非常简单:一个TCP套接字在本地主机上侦听,另一个TCP套接字连接到侦听套接字(从同一程序,在同一台计算机上),然后一个无限循环开始使用客户端套接字将256kB大小的数据包发送到服务器套接字。
间隔为1000毫秒的计时器将从两个插槽向控制台输出一个字节计数器,以使带宽可见,然后将其重置以进行下一次测量。
我已经意识到数据包大小的最佳点是256kB,套接字的缓冲区大小是64kB,以获得最大的吞吐量。
使用async/await类型方法,我可以达到
~370MB/s (~3.2gbps) on Windows, ~680MB/s (~5.8gbps) on Linux with mono
Run Code Online (Sandbox Code Playgroud)
使用BeginReceive/EndReceive/BeginSend/EndSend类型方法,我可以达到
~580MB/s (~5.0gbps) on Windows, ~9GB/s (~77.3gbps) on Linux with mono
Run Code Online (Sandbox Code Playgroud)
使用SocketAsyncEventArgs/ReceiveAsync/SendAsync类型方法,我可以达到
~1.4GB/s (~12gbps) on Windows, ~1.1GB/s (~9.4gbps) on Linux with mono
Run Code Online (Sandbox Code Playgroud)
问题如下:
async/await方法是最慢的,所以我不会使用它们BeginReceive/EndReceiveBeginAccept/EndAccept在Linux / mono下,方法和方法一起启动了新的异步线程,套接字的每个新实例都非常慢(当ThreadPoolmono中没有更多线程启动新线程,但是创建25个连接实例时大约需要5分钟 …我正在尝试使用cocoaasyncsocket库附带的echo服务器示例的修改版本执行以下操作:
1)打开与作为服务器的python脚本的连接
2)发送数据//工作,但委托不激活
3)接收数据//委托不激活
4)断开//不断开,显然还在我的帖子里
目前,我在didFinishLaunchingWithOptions委托中打开一个连接,然后尝试在didConnectToHost委托中发送数据.然后,我尝试读取从客户端返回的数据,然后断开连接.
我能够打开一个连接并发送数据(服务器验证为收到),但didWriteDataWithTag委托永远不会触发.但是,服务器接收数据.然后服务器会激活一些数据,但didReadData也不会触发.
除了读/写代理没有触发的事实,似乎我组织我的代码的方式不对,但我不确定这在事件驱动的系统中看起来如何与运行循环相反(我'在事件驱动的东西+网络新手.如果我的一系列行动的各自的完成是由他们的代表触发的,那么代表们是否应该分享某种消息 - 即我们收到了"xxx"消息,请回写"yyy"?我更喜欢有一个功能来管理所有这些.这样做有规范的方法吗?
IPhoneConnectTestAppDelegate.m(片段)
- (void)localConnect {
NSError *error = nil;
if (![asyncSocket connectToHost:@"localhost" onPort:5000 error:&error]) {
DDLogError(@"Error connecting: %@", error);
}
}
- (void)disconnect {
[asyncSocket setDelegate:nil];
[asyncSocket disconnect];
[asyncSocket release];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Setup our socket (GCDAsyncSocket).
dispatch_queue_t mainQueue = dispatch_get_main_queue();
asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];
[self localConnect];
// Add the view controller's view to the window and display.
[window addSubview:viewController.view];
[window makeKeyAndVisible];
} …Run Code Online (Sandbox Code Playgroud) 我在Linux上用c ++编写了一个简单的tcp/ip服务器.我正在使用异步套接字和epoll.当我收到EPOLLIN事件时,是否有可能找出可供读取的字节数?
asyncsocket ×10
c# ×5
sockets ×4
asynchronous ×2
iphone ×2
linux ×2
objective-c ×2
tcp ×2
.net ×1
c++ ×1
cocoa ×1
cocoa-touch ×1
nsrunloop ×1
nsthread ×1
serversocket ×1
sigpipe ×1
tcpclient ×1
udp ×1