Chinaunix首页 | 论坛 | 博客
  • 博客访问: 55833
  • 博文数量: 27
  • 博客积分: 1505
  • 博客等级: 上尉
  • 技术积分: 304
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-19 13:25
文章分类

全部博文(27)

文章存档

2015年(14)

2014年(4)

2013年(2)

2012年(1)

2011年(4)

2010年(2)

我的朋友

分类: Java

2015-04-08 10:31:44

Linux下端口占用问题

1、  环境

操作系统:centos 6.3 64

JDKOpenJDK1.7

2、  前提

1)         C程序通过shell脚本来启动一个java程序。

2)         C程序需要打开一个TCP端口等待客户端连接;(C程序占用的端口为15001

3)         JAVA程序实现了一个RMI服务。(为RMI指定了一个端口6000

4)         C进程重启时,不重启JAVA进程;

3、  问题

1)         启动java程序时,经常会占用C程序要监听的TCP端口;

问题分析:

a)         通过netstat查看java进程所占的端口会发现,其除了占用了6000端口外,还会多绑定一个额外端口;通过多次启动java进程发现,该额外端口不定,有时占用15001,有时又占用别的端口;

b)         通过上面的观察,就怀疑RMI机制会不会就要多分一个端口。通过了解RMI的原理得知:

RMI需要有2个端口,一个负责注册服务(默认1009),另一个提供服务。 

分析代码中分配端口的地方:

以下代码是打开一个注册服务,并指定了端口为6000,该端口负责注册RMI服务;

LocateRegistry.createRegistry(6000);  

提供RMI服务的类继承了UnicastRemoteObject类,并在构造方法中掉用了UnicastRemoteObject的无参的构造方法;而UnicastRemoteObject内部又会执行一个带有端口参数的构造方法,并默认传入了0RMI的机制就是如果传入的参数是0,那么系统就会随机分配一个端口给RMI服务;

           解决方法:

                   直接调用UnicastRemoteObject中带端口参数的构造方法,指定一个端口为6001;之后启动JAVA程序就不会再随机分配端口了。

2)         解决了以上问题后,又运行了一段时间,发现C进程重启时,15001又会别java进程占用。

问题分析:

a)         通过几次实验发现,只要C进程关闭,15001端口就被分配到java进程上。而且过一会该端口就会自动关闭,通过抓包发现该端口上吐出的数据也是C进程传输的内容。可以确定C进程关闭时,由于数据还没有发送完,端口没有立即关闭,而是发送完后,等一个TIMEWait时间后才关闭。

b)         初步怀疑是Linux系统进程管理机制的问题,当父进程被杀死后,子进程会继承父进程的端口资源。但是通过ps命令发现java进程此时的父进程为init进程。在C进程没有被杀死的情况下,其父进程也为init进程。这样似乎不是该问题,但是经过仔细分析还是能得出上述结果的,如下分析过程:

 

system()会调用fork()产生子进程,由子进程来调用/bin/sh-c
string
来执行参数string字符串所代表的命令,此命令执行完后随
即返回原调用的进程。

2、    popen(建立管道I/O

popen()会调用fork()产生子进程,然后从子进程中调用/bin/sh -c
来执行参数command的指令。

3、    使用fork()新建子进程,然后调用exec函数族;

用fork函数创建子进程后,子进程往往要调用一种exe以执行另一个程序。当进程调用一种exe时,该进程完全由新程序代换,而新程序则从其 main函数开始执行。因为调用exec并不创建新进程,所以前后的进程ID并未改变。exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。有六种不同的exe可供使用,它们常常被统称为exec函数。

解决方法:

从分析可以得知,要想解决当前问题,就是阻止子进程继承父进程的资源;当前C进程是通过system函数来执行shell脚本,必然会继承父进程的资源;通过c语言调用shell的三个方法看,只有间接调用exec函数才会打乱继承关系,因为它会用新的程序来占用新fork的子进程,继承而来的资源也都会覆盖掉,即就不存在继承关系了。

 

阅读(728) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~