iOS AsyncSocket 與 Java Netty 的簡(jiǎn)單socket使用

Netty提供異步的权均、事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架和工具,用以快速開發(fā)高性能髓绽、高可靠性的網(wǎng)絡(luò)服務(wù)器和客戶端程序敛苇。也就是說,Netty 是一個(gè)基于NIO的客戶顺呕,服務(wù)器端編程框架枫攀,使用Netty 可以確保你快速和簡(jiǎn)單的開發(fā)出一個(gè)網(wǎng)絡(luò)應(yīng)用,例如實(shí)現(xiàn)了某種協(xié)議的客戶株茶,服務(wù)端應(yīng)用来涨。Netty相當(dāng)簡(jiǎn)化和流線化了網(wǎng)絡(luò)應(yīng)用的編程開發(fā)過程,例如忌卤,TCP和UDP的socket服務(wù)開發(fā)扫夜。

AsyncSocket 是基于CFSocket與CFStream封裝的TCP/IP socket的網(wǎng)絡(luò)庫楞泼,它提供了異步操作,本地cocoa類的delegate支持驰徊。主要關(guān)鍵特新如下:

  1. 隊(duì)列的可選超時(shí)的非阻塞的讀和寫。比如:你告訴它讀寫的內(nèi)容堕阔,他將在完成的時(shí)候通知你.
  2. socket的自動(dòng)接收棍厂。如果你告訴它接受連接,它將為每個(gè)連接建立新的實(shí)例供你調(diào)用超陆。你也可以選擇立即斷開連接牺弹。
  3. 支持Delegate,delegate方法中包含錯(cuò)誤浦马、連接,接收张漂,完整的讀寫晶默、進(jìn)度、以及斷開連接航攒。
  4. 不基于線程(thread)而基于Run-loop.雖然你可以主線程或者子線程中可以使用磺陡,但是木有必要。它使用NSRunLoop異步調(diào)用委托的方法漠畜。委托方法包括一個(gè)socket參數(shù),允許區(qū)分多個(gè)實(shí)例币他。
  5. 自包裝在一個(gè)類中。你不需要操作流或Socket憔狞。它會(huì)自己處理蝴悉。
  6. 支持基于IPv4、IPv6的TCP流瘾敢。

github地址:https://github.com/roustem/AsyncSocket

第一步:
下載和安裝
Netty:使用maven安裝Netty

AsyncSocket:使用cocoapods安裝

第二步:服務(wù)端創(chuàng)建
1.HelloServer

package com.nettypro.io;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class HelloServer {

/*
 * 創(chuàng)建服務(wù)端監(jiān)聽端口
 */
 
private static final int portNumber = 8080;
public static void main(String[] args) throws InterruptedException {
    EventLoopGroup boosGroup = new NioEventLoopGroup();
    EventLoopGroup workerGroup = new NioEventLoopGroup();
     
    try {
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(boosGroup, workerGroup);
        bootstrap.channel(NioServerSocketChannel.class);
        bootstrap.childHandler(new HelloServerInitializer())
        .childOption(ChannelOption.SO_KEEPALIVE, true); // (6);
         
        //服務(wù)器綁定端口監(jiān)聽
        ChannelFuture channelFuture = bootstrap.bind(portNumber).sync();
        //監(jiān)聽服務(wù)器關(guān)閉監(jiān)聽
        channelFuture.channel().closeFuture().sync();
    }finally{
            boosGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
    }
     
  }
}

2.HelloServerInitializer

package com.nettypro.io;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class HelloServerInitializer extends ChannelInitializer<SocketChannel> {

@Override
protected void initChannel(SocketChannel arg0) throws Exception {
    // TODO Auto-generated method stub
    //ChannelPipeline 可以理解為消息傳送通道 通道一旦建立 持續(xù)存在
    ChannelPipeline channelPipeline = arg0.pipeline();
    //為通道添加功能
    //字符串解碼  編碼
    channelPipeline.addLast("decoder",new StringDecoder());
    channelPipeline.addLast("encoder", new StringEncoder());
     
    //添加自主邏輯   
    channelPipeline.addLast(new HelloServerHandler());
  }
}

3.HelloServerHandler

package com.nettypro.io;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Scanner;

import javax.xml.crypto.Data;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class HelloServerHandler extends     SimpleChannelInboundHandler<String> {

@Override
protected void channelRead0(ChannelHandlerContext arg0, String arg1)
        {
    // TODO Auto-generated method stub
    System.out.println(arg0.channel().remoteAddress()+"   ----channelRead0");
    //收到消息直接打印
    System.out.println(arg0.channel().remoteAddress()+"   MSG:  "+ arg1);
    //回復(fù)消息
    Scanner scanner = new Scanner(System.in);
    String msgString = scanner.nextLine()+"\n";
    System.out.println(arg0.channel().remoteAddress()+"  msgString:  "+ msgString);
     
    arg0.writeAndFlush(msgString);
}
 
 
/**
 * channel被激活時(shí)調(diào)用
 */
@Override
public void channelActive(ChannelHandlerContext ctx){
    // TODO Auto-generated method stub
     
    System.out.println(ctx.channel().remoteAddress()+"   ----Acrive");
    try {
        ctx.writeAndFlush("Welcome you to here"+InetAddress.getLocalHost().getHostName());
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }
  }
}

第三步:客戶端的創(chuàng)建:

#import "ViewController.h"
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <unistd.h>

#import "AsyncSocket.h"
@interface ViewController ()<AsyncSocketDelegate>

@property (nonatomic, retain) NSTimer *heartTimer;
@property (nonatomic, retain) AsyncSocket *ay;
@property (strong, nonatomic) IBOutlet UITextField   *msgTF;
@property (strong, nonatomic) IBOutlet UITextView *showTV;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    self.ay = [[AsyncSocket alloc] initWithDelegate:self];
    [self.ay connectToHost:@"localhost" onPort:8080 error:nil];
    self.ay.delegate = self;
 
    NSString *msg = @"HelloNetty";
    [self.ay writeData:[msg dataUsingEncoding:NSUTF8StringEncoding]
       withTimeout:10.0f
               tag:101];
 
    [self.ay readDataWithTimeout:-1 tag:0];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
  }

- (IBAction)sendAction:(UIButton *)sender {
    if (self.msgTF.text.length != 0) {
     
        self.showTV.text = [NSString stringWithFormat:@"%@\n客戶端說:%@",self.showTV.text,self.msgTF.text];
     
        [self.ay writeData:[self.msgTF.text dataUsingEncoding:NSUTF8StringEncoding]
           withTimeout:10.0f
                   tag:101];
     
        [self.ay readDataWithTimeout:-1 tag:0];
     
        self.msgTF.text = nil;
    }
}

#pragma mark
#pragma mark --AsyncSocketDelegate--
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
 
    NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"msg-----%@",msg);
 
    if (self.showTV.text.length == 0)
    {
        self.showTV.text = [NSString stringWithFormat:@"服務(wù)器說:%@",msg];
    }
    else
    {
        self.showTV.text = [NSString stringWithFormat:@"%@\n服務(wù)器說:%@",self.showTV.text,msg];
    }
 
    [self.ay readDataWithTimeout:-1 tag:0];
 
}

- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
     [self.ay readDataWithTimeout:-1 tag:0];
}

-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
    NSLog(@"didConnectToHost    %@------%d",host,port);
    [self.ay readDataWithTimeout:-1 tag:0];
}

-(void)onSocket:(AsyncSocket *)sock didReadPartialDataOfLength:(NSUInteger)partialLength tag:(long)tag
{
    NSLog(@"Received bytes: %lu",(unsigned long)partialLength);
}

@end

運(yùn)行結(jié)果:

wKiom1Yy5IfxBtr7AAGihZfj6Ak498.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拍冠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子廉丽,更是在濱河造成了極大的恐慌倦微,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件正压,死亡現(xiàn)場(chǎng)離奇詭異欣福,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)焦履,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門拓劝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嘉裤,你說我怎么就攤上這事郑临。” “怎么了屑宠?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵厢洞,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我典奉,道長(zhǎng)躺翻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任卫玖,我火速辦了婚禮公你,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘假瞬。我一直安慰自己陕靠,他們只是感情好迂尝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著剪芥,像睡著了一般垄开。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上税肪,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天说榆,我揣著相機(jī)與錄音,去河邊找鬼寸认。 笑死签财,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的偏塞。 我是一名探鬼主播唱蒸,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼灸叼!你這毒婦竟也來了神汹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤古今,失蹤者是張志新(化名)和其女友劉穎屁魏,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捉腥,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡氓拼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抵碟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桃漾。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖拟逮,靈堂內(nèi)的尸體忽然破棺而出撬统,到底是詐尸還是另有隱情,我是刑警寧澤敦迄,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布恋追,位于F島的核電站,受9級(jí)特大地震影響罚屋,放射性物質(zhì)發(fā)生泄漏苦囱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一沿后、第九天 我趴在偏房一處隱蔽的房頂上張望沿彭。 院中可真熱鬧朽砰,春花似錦尖滚、人聲如沸喉刘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽睦裳。三九已至,卻和暖如春撼唾,著一層夾襖步出監(jiān)牢的瞬間廉邑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工倒谷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓谜诫,卻偏偏與公主長(zhǎng)得像碴卧,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子抖格,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • iPhone的標(biāo)準(zhǔn)推薦是CFNetwork 庫編程诺苹,其封裝好的開源庫是 cocoa AsyncSocket庫,用它...
    Ethan_Struggle閱讀 2,239評(píng)論 2 12
  • 第一部分雹拄、概念的理解1收奔、什么是Socket?Socket又稱之為“套接字”滓玖,是系統(tǒng)提供的用于網(wǎng)絡(luò)通信的方法坪哄。它的實(shí)...
    Hevin_Chen閱讀 2,450評(píng)論 0 5
  • 轉(zhuǎn)載:http://www.cocoachina.com/ios/20170615/19529.html 參考:h...
    F麥子閱讀 4,007評(píng)論 3 2
  • CocoaAsyncSocket支持tcp和udp。其中: AsyncSocket類是支持TCP的 AsyncUd...
    鄭軍紅閱讀 1,640評(píng)論 0 2
  • socket势篡,究竟是什么東東损姜,面試時(shí),筆試有他殊霞,面試也有他摧阅,如果做智能硬件,肯定會(huì)用到socket绷蹲,所以棒卷,今天帶大...
    AirZilong閱讀 2,406評(píng)論 2 24