我在云服務(wù)器上使用netty中,在進(jìn)行端口綁定時(shí),調(diào)用ServerBootstrap的bind(String inetHost, int inetPort)方法時(shí),如果inetHost參數(shù)填寫(xiě)公網(wǎng)ip,在啟動(dòng)時(shí)就報(bào)錯(cuò)java.net.BindException: Cannot assign requested address,參數(shù)換成127.0.0.1或者0.0.0.0就沒(méi)事,這是什么原因?qū)е碌陌?
一開(kāi)始我們是在學(xué)校服務(wù)器上開(kāi)發(fā),一直都填的內(nèi)網(wǎng)ip,無(wú)法公網(wǎng)訪問(wèn),最近放假了老師讓我把服務(wù)器轉(zhuǎn)移到云上,結(jié)果就死活啟動(dòng)不了,現(xiàn)在問(wèn)題解決了,就是不知道為啥不能綁定公網(wǎng)ip
Netty的引導(dǎo)類(lèi)為應(yīng)用程序的網(wǎng)絡(luò)層配置提供了容器,這涉及將一個(gè)進(jìn)程綁定到某個(gè)指定的端口,或者將一個(gè)進(jìn)程連接到另一個(gè)運(yùn)行在某個(gè)指定主機(jī)的指定端口上的進(jìn)程。
“服務(wù)器”和“客戶(hù)端”實(shí)際上表示了不同的網(wǎng)絡(luò)行為:是監(jiān)聽(tīng)傳入的連接還是建立到一個(gè)或者多個(gè)進(jìn)程的連接。
面向連接的協(xié)議:請(qǐng)記住,嚴(yán)格來(lái)說(shuō),“連接”這個(gè)屬于僅適用于面向連接的協(xié)議,如TCP、其保證了兩個(gè)連接端點(diǎn)之間消息的有序傳遞。
因此,有兩種類(lèi)型的引導(dǎo):一種用于客戶(hù)端(簡(jiǎn)單稱(chēng)為Bootstrap),而另一種(ServerBootstrap)用于服務(wù)器。無(wú)論你的應(yīng)用程序使用哪些協(xié)議或者處理哪種類(lèi)型的數(shù)據(jù),唯一決定它使用哪種引導(dǎo)類(lèi)的是它是作為一個(gè)客戶(hù)端還是作為一個(gè)服務(wù)器。
這兩種類(lèi)型的引導(dǎo)類(lèi)之間的第一個(gè)區(qū)別已經(jīng)討論過(guò)了:ServerBootstrap將綁定到一個(gè)端口,因?yàn)榉?wù)器必須要監(jiān)聽(tīng)連接,而B(niǎo)ootstrap則由想要連接到遠(yuǎn)程節(jié)點(diǎn)的客戶(hù)端應(yīng)用程序所使用的
代碼案例:使用NIO TCP傳輸?shù)目蛻?hù)端
EventLoopGroup group = new NioEventLoopGroup();
//創(chuàng)建一個(gè)Bootstrap類(lèi)的實(shí)例以創(chuàng)建和連接新的客戶(hù)端Channel
Bootstrap bootstrap = new Bootstrap();
//設(shè)置EventLoopGroup,提供用于處理Channel事件的EventLoop
bootstrap.group(group)
//指定要使用的Channel實(shí)現(xiàn)
.channel(NioSocketChannel.class)
//指定用于Channel事件和數(shù)據(jù)的ChannelInboundHandler
.handler(new SimpleChannelInboundHandler<ByteBuf>() {
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf)
throws Exception {
System.out.println("Received data");
}
});
ChannelFuture future = bootstrap.connect(
//連接到遠(yuǎn)程主機(jī)
new InetSocketAddress("www.myself.com",80)
);
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture) throws Exception {
if (channelFuture.isSuccess()){
System.out.println("Connection established");
} else {
System.out.println("Connection attempt failed");
channelFuture.cause().printStackTrace();
}
}
});
實(shí)現(xiàn)服務(wù)器引導(dǎo)
NioEventLoopGroup group = new NioEventLoopGroup();
//創(chuàng)建ServerBootstrap
ServerBootstrap bootstrap = new ServerBootstrap();
//設(shè)置EventLoopGroup,其提供了用于處理Channel事件的EventLoop
bootstrap.group(group)
//指定要使用的Channel實(shí)現(xiàn)
.channel(NioServerSocketChannel.class)
.childHandler(new SimpleChannelInboundHandler<ByteBuf>() {
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf)
throws Exception {
System.out.println("Received data");
}
});
//通過(guò)配置好的ServerBootstrap的實(shí)例綁定該Channel
ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080));
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture) throws Exception {
if (channelFuture.isSuccess()){
System.out.println("Server bound");
} else {
System.out.println("Bound attempt failed");
channelFuture.cause().printStackTrace();
}
}
});
客戶(hù)端引導(dǎo)
//創(chuàng)建ServerBootstrap以創(chuàng)建和綁定新的Channel
ServerBootstrap bootstrap = new ServerBootstrap();
//設(shè)置EventLoopGroup,其將提供用以處理Channel事件的EventLoop
bootstrap.group(new NioEventLoopGroup(),new NioEventLoopGroup())
//指定Channel的實(shí)現(xiàn)
.channel(NioServerSocketChannel.class)
//注冊(cè)一個(gè)ChannelInitializerImpl的實(shí)例來(lái)設(shè)置ChannelPipeline
.childHandler(new ChannelInitializerImpl());
ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080));
future.sync();*/
/*//創(chuàng)建一個(gè)AttributeKey以標(biāo)識(shí)該屬性
final AttributeKey<Integer> id = AttributeKey.valueOf("ID");
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(new NioEventLoopGroup())
.channel(NioSocketChannel.class)
.handler(new SimpleChannelInboundHandler<ByteBuf>() {
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
//使用AttributeKey檢索屬性以及它的值
Integer idValue = ctx.channel().attr(id).get();
//do something with the idValue
}
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf)
throws Exception {
System.out.println("Received data");
}
});
//設(shè)置ChannelOption其將在connect()或者bind()方法被調(diào)用時(shí)被設(shè)置到已經(jīng)創(chuàng)建的Channel上
bootstrap.option(ChannelOption.SO_KEEPALIVE,true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS,5000);
//存儲(chǔ)該id屬性
bootstrap.attr(id,123456);
ChannelFuture future = bootstrap.connect(new InetSocketAddress("www.myself.com",80));
future.syncUninterruptibly();雖然已經(jīng)采納了答案,但我還是想回答一下這個(gè)問(wèn)題。
首先,對(duì)于一個(gè)程序來(lái)講,它所綁定的IP只能是其所在機(jī)器(無(wú)論物理機(jī)還是虛擬機(jī))上的某個(gè)網(wǎng)卡的IP地址,這個(gè)你可以到機(jī)器上運(yùn)行ifconfig查看。
其次,所謂綁定的含義是規(guī)定程序能夠監(jiān)聽(tīng)到哪個(gè)目的地IP的IP包,比如機(jī)器有兩個(gè)網(wǎng)卡A和B,IP地址分別是AIP和BIP,你的程序綁定AIP,那么操作系統(tǒng)只會(huì)將目的地是AIP的IP包轉(zhuǎn)發(fā)給你的程序。0.0.0.0是特殊的,它代表著能夠轉(zhuǎn)發(fā)目的地IP是機(jī)器上任意IP的IP包到你的程序。
最后,為何可以通過(guò)公網(wǎng)IP訪問(wèn)到你的機(jī)器?這是因?yàn)樵品?wù)商給你做了NAT,而這個(gè)地址你的機(jī)器是不知道的,也不屬于你的機(jī)器上的任意一張網(wǎng)卡,所以你無(wú)法綁定。
PS. 你應(yīng)該去學(xué)一些基礎(chǔ)網(wǎng)絡(luò)知識(shí)??梢哉乙槐綜CNA或者HCNA的書(shū)看看。
北大青鳥(niǎo)APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專(zhuān)業(yè)的國(guó)家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
北大課工場(chǎng)是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國(guó)家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國(guó)制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級(jí)產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國(guó)職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開(kāi)發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_(kāi)發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開(kāi)發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開(kāi)發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開(kāi)發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。