java 进程间通讯的有几种方法
JAVA进程间通信的方法主要有以下几种:
(1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
(2)命名管道(named pipe):命名管道克服了管道没有名字的限制,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。
(3)信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送 信号给进程本身。
(4)消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。
(5)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。
(6)内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。
(7)信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
(8)套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。
非调试模式下打开应用。
使用socket在as3客户端和java服务器之间通信,发现某些情况下如果客户端长时间不与服务器进行通信(15-30min以上),再次进入由客户端向服务器发送消息,服务器无反应。过一会,连接断开。这种情况是在非调试模式下打开应用。
可以用TCP或UDP协议。两者不同之处在于,TCP要建立服务器客户端必须和服务器连接,才能和其他客户进行联系。
但UDF不需要,只要知道对方的IP和端口,就可以连接任何一台客户端。
想这样类似QQ的代码很多,晚上搜一下就有。这里给一个客户端和服务器。
-------------------
import javaawt;
import javaawtevent;
import javanet;
import javaio;
import javautilloggingLevel;
import javautilloggingLogger;
class myframe extends Frame implements ActionListener,WindowListener,Runnable,KeyListener
{
Thread mythread = new Thread(this);
Socket mysocket;
DataInputStream in;
DataOutputStream out;
Label label_ip = new Label("IP");
Label label_port = new Label("Port");
TextField text_ip = new TextField("127110",15);
TextField text_port = new TextField("8888",15);
Button button_connect = new Button("连接");
TextArea text_area_show = new TextArea();
TextField text_send = new TextField(45);
Button button_send = new Button("发送");
myframe()
{
Panel panel1 = new Panel();
Panel panel2 = new Panel();
panel1setLayout(new FlowLayout());
panel1add(label_ip);
panel1add(text_ip);
panel1add(label_port);
panel1add(text_port);
panel1add(button_connect);
panel2setLayout(new FlowLayout());
panel2add(text_send);
panel2add(button_send);
add(panel1,BorderLayoutNORTH);
add(text_area_show,BorderLayoutCENTER);
add(panel2,BorderLayoutSOUTH);
text_sendaddKeyListener(this);
button_connectaddActionListener(this);
button_sendaddActionListener(this);
addWindowListener(this);
thissetTitle("客户端");
setBounds(200,200,400,350);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if(egetSource() == button_connect)
{
try
{
String ip = null,port = null;
ip = text_ipgetText();
port = text_portgetText();
mysocket = new Socket(ip, IntegerparseInt(port));
in = new DataInputStream(mysocketgetInputStream());
out = new DataOutputStream(mysocketgetOutputStream());
}
catch (UnknownHostException ex)
{
LoggergetLogger(myframeclassgetName())log(LevelSEVERE, null, ex);
}
catch (IOException ex)
{
LoggergetLogger(myframeclassgetName())log(LevelSEVERE, null, ex);
}
mythreadstart();
}
if(egetSource() == button_send)
{
if(mysocketisConnected() == true)
{
String temp = null;
temp = text_sendgetText();
try
{
outwriteUTF(temp);
text_sendsetText(null);
}
catch (IOException ex)
{
LoggergetLogger(myframeclassgetName())log(LevelSEVERE, null, ex);
}
}
}
}
public void run()
{
while(true)
{
String temp = null;
try
{
temp = inreadUTF();
}
catch (IOException ex)
{
text_area_showappend("服务器退出\n");
return;
}
temp += "\n";
text_area_showappend(temp);
}
}
public void keyPressed(KeyEvent e)
{
if(egetKeyCode() == KeyEventVK_ENTER)
{
String temp = null;
temp = text_sendgetText();
try
{
outwriteUTF(temp);
}
catch (IOException ex)
{
LoggergetLogger(myframeclassgetName())log(LevelSEVERE, null, ex);
}
}
}
public void windowClosing(WindowEvent e)
{
Systemexit(0);
}
public void windowOpened(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
}
public class mywindow
{
public static void main(String argv[])
{
myframe f = new myframe();
}
}
--------------------------------
import javaawteventWindowAdapter;
import javaawteventWindowEvent;
import javaioDataInputStream;
import javaioDataOutputStream;
import javaioIOException;
import javanetServerSocket;
import javanetSocket;
import javautilLinkedList;
import javautilloggingLevel;
import javautilloggingLogger;
import javaxswingJTextArea;
class RecvMegSock extends Thread
{
LinkedList SocketList = null;
Socket ClientSock = null;
JTextArea jTextArea1;
RecvMegSock(LinkedList list,Socket s,JTextArea t)
{
SocketList = list;
jTextArea1 = t;
ClientSock = s;
start();
}
public void run()
{
while(true)
{
try
{
DataInputStream in = new DataInputStream(ClientSockgetInputStream());
String word = inreadUTF();
jTextArea1setText(jTextArea1getText() + word + "\n");
for(int i = 0;i < SocketListsize();i++)
{
Socket s = (Socket)SocketListget(i);
DataOutputStream out = new DataOutputStream(sgetOutputStream());
outwriteUTF(word);
}
}
catch (IOException ex)
{
for(int i = 0;i < SocketListsize();i++)
{
Socket s = (Socket)SocketListget(i);
if(s == ClientSock)
SocketListremove(s);
}
for(int i = 0;i < SocketListsize();i++)
{
Socket s = (Socket)SocketListget(i);
try
{
DataOutputStream out = new DataOutputStream(sgetOutputStream());
outwriteUTF(ClientSockgetInetAddress() + "已经退出!!\n");
}
catch (IOException ex1)
{
LoggergetLogger(RecvMegSockclassgetName())log(LevelSEVERE, null, ex1);
}
}
jTextArea1setText(jTextArea1getText() + ClientSockgetInetAddress() + "已经退出!!" + "\n");
return;
}
}
}
}
class AcceptSockThread extends Thread
{
ServerSocket ServerSock = null;
LinkedList SocketList = null;
JTextArea TextArea;
AcceptSockThread(ServerSocket s,LinkedList list,JTextArea t)
{
ServerSock = s;
SocketList = list;
TextArea = t;
start();
}
public void run()
{
while(true)
{
Socket ClientSock = null;
try
{
boolean same = false;
ClientSock = ServerSockaccept(); /
for(int i = 0;i < SocketListsize();i++)
{
Socket s = (Socket)SocketListget(i);
if(sgetInetAddress()equals(ClientSockgetInetAddress()) && sgetPort() == ClientSockgetPort())
{
DataOutputStream out = new DataOutputStream(sgetOutputStream());
outwriteUTF(ClientSockgetInetAddress() + "你已经连接了服务器!!\n");
same = true;
}
}
if(same == true)
continue;
/
new RecvMegSock(SocketList,ClientSock,TextArea);
SocketListadd(ClientSock);
for(int i = 0;i < SocketListsize();i++)
{
Socket s = (Socket)SocketListget(i);
DataOutputStream out = new DataOutputStream(sgetOutputStream());
outwriteUTF(ClientSockgetInetAddress() + "成功连接服务器\n");
}
TextAreasetText(TextAreagetText() + ClientSockgetInetAddress() + "连接到服务器\n");
}
catch (IOException ex)
{
LoggergetLogger(AcceptSockThreadclassgetName())log(LevelSEVERE, null, ex);
}
}
}
}
public class ServerDialog extends javaxswingJDialog
{
ServerSocket Server = null;
LinkedList SocketList = null;
public ServerDialog(javaawtFrame parent, boolean modal)
{
super(parent, modal);
initComponents();
try
{
Server = new ServerSocket(8888);
SocketList = new LinkedList();
new AcceptSockThread(Server,SocketList,jTextArea1);
}
catch (IOException ex)
{
LoggergetLogger(ServerDialogclassgetName())log(LevelSEVERE, null, ex);
}
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jScrollPane1 = new javaxswingJScrollPane();
jTextArea1 = new javaxswingJTextArea();
jTextField1 = new javaxswingJTextField();
jButton1 = new javaxswingJButton();
setDefaultCloseOperation(javaxswingWindowConstantsDISPOSE_ON_CLOSE);
getContentPane()setLayout(null);
jTextArea1setColumns(20);
jTextArea1setEditable(false);
jTextArea1setRows(5);
jScrollPane1setViewportView(jTextArea1);
getContentPane()add(jScrollPane1);
jScrollPane1setBounds(10, 10, 380, 250);
getContentPane()add(jTextField1);
jTextField1setBounds(10, 270, 290, 21);
jButton1setText("发送");
jButton1addActionListener(new javaawteventActionListener() {
public void actionPerformed(javaawteventActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
getContentPane()add(jButton1);
jButton1setBounds(310, 270, 80, 25);
pack();
}// </editor-fold>//GEN-END:initComponents
private void jButton1ActionPerformed(javaawteventActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
if(SocketListsize() == 0)
{
jTextArea1setText(jTextArea1getText() + "没有人连接!!" + "\n");
return;
}
for(int i = 0;i < SocketListsize();i++)
{
DataOutputStream out;
try
{
out = new DataOutputStream(((Socket) SocketListget(i))getOutputStream());
if(jTextField1getText() != null)
outwriteUTF(jTextField1getText());
}
catch (IOException ex)
{
LoggergetLogger(ServerDialogclassgetName())log(LevelSEVERE, null, ex);
}
}
jTextArea1setText(jTextArea1getText() + jTextField1getText() + "\n");
}//GEN-LAST:event_jButton1ActionPerformed
public static void main(String args[])
{
ServerDialog dlg = new ServerDialog(null,true);
dlgsetBounds(300, 200, 400, 325);
dlgaddWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
Systemexit(0);
}
});
dlgsetVisible(true);
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javaxswingJButton jButton1;
private javaxswingJScrollPane jScrollPane1;
private javaxswingJTextArea jTextArea1;
private javaxswingJTextField jTextField1;
// End of variables declaration//GEN-END:variables
}
服务器告知双方对方的ip地址,并协调由哪一方主动连接。
如 协调结果是: 把c2的地址告诉c1,让c1主动连接c2,让c2打开端口等待连接。
要考虑认证问题,比如c2如何知道连接上来的是c1,而不是其他人,就需要有认证机制。
另外要考虑内网问题。由于从外部连接内网里面的IP地址是相当繁琐复杂的,所以需要特别的机制处理。
您好,提问者:
首先IOException:Socket closed这个错误表示数据发送完毕后客户端或者服务器已经关闭了,也就是close()了。一般是没有while(true)之类。
其次javaioEOFException这个错误是指发送的数据始终没有读到结尾,socket读写方式是以\r\n方式进行结束的,Socket有一个方法,如下代码:
shutdownInput()此套接字的输入流置于“流的末尾”。
//当数据发送时,最后调用一下这个方法,已告诉ServerSocket我已经发送完毕,不要继续读了
下面是一个简单的通讯实例,进行Server和Client之间的文件传输。。如果是简单的文本传输的话简化掉文本操作的内容即可。。
1服务器端
package sterning;
import javaioBufferedInputStream;
import javaioDataInputStream;
import javaioDataOutputStream;
import javaioFile;
import javaioFileInputStream;
import javanetServerSocket;
import javanetSocket;
public class ServerTest {
int port = 8821;
void start() {
Socket s = null;
try {
ServerSocket ss = new ServerSocket(port);
while (true) {
// 选择进行传输的文件
String filePath = "D:\\librar";
File fi = new File(filePath);
Systemoutprintln("文件长度:" + (int) filength());
// public Socket accept() throws
// IOException侦听并接受到此套接字的连接。此方法在进行连接之前一直阻塞。
s = ssaccept();
Systemoutprintln("建立socket链接");
DataInputStream dis = new DataInputStream(new BufferedInputStream(sgetInputStream()));
disreadByte();
DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
DataOutputStream ps = new DataOutputStream(sgetOutputStream());
//将文件名及长度传给客户端。这里要真正适用所有平台,例如中文名的处理,还需要加工,具体可以参见Think In Java 4th里有现成的代码。
pswriteUTF(figetName());
psflush();
pswriteLong((long) filength());
psflush();
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];
while (true) {
int read = 0;
if (fis != null) {
read = fisread(buf);
}
if (read == -1) {
break;
}
pswrite(buf, 0, read);
}
psflush();
// 注意关闭socket链接哦,不然客户端会等待server的数据过来,
// 直到socket超时,导致数据不完整。
fisclose();
sclose();
Systemoutprintln("文件传输完成");
}
} catch (Exception e) {
eprintStackTrace();
}
}
public static void main(String arg[]) {
new ServerTest()start();
}
}
2socket的Util辅助类
package sterning;
import javanet;
import javaio;
public class ClientSocket {
private String ip;
private int port;
private Socket socket = null;
DataOutputStream out = null;
DataInputStream getMessageStream = null;
public ClientSocket(String ip, int port) {
thisip = ip;
thisport = port;
}
/ //
创建socket连接
@throws Exception
exception
/
public void CreateConnection() throws Exception {
try {
socket = new Socket(ip, port);
} catch (Exception e) {
eprintStackTrace();
if (socket != null)
socketclose();
throw e;
} finally {
}
}
public void sendMessage(String sendMessage) throws Exception {
try {
out = new DataOutputStream(socketgetOutputStream());
if (sendMessageequals("Windows")) {
outwriteByte(0x1);
outflush();
return;
}
if (sendMessageequals("Unix")) {
outwriteByte(0x2);
outflush();
return;
}
if (sendMessageequals("Linux")) {
outwriteByte(0x3);
outflush();
} else {
outwriteUTF(sendMessage);
outflush();
}
} catch (Exception e) {
eprintStackTrace();
if (out != null)
outclose();
throw e;
} finally {
}
}
public DataInputStream getMessageStream() throws Exception {
try {
getMessageStream = new DataInputStream(new BufferedInputStream(socketgetInputStream()));
return getMessageStream;
} catch (Exception e) {
eprintStackTrace();
if (getMessageStream != null)
getMessageStreamclose();
throw e;
} finally {
}
}
public void shutDownConnection() {
try {
if (out != null)
outclose();
if (getMessageStream != null)
getMessageStreamclose();
if (socket != null)
socketclose();
} catch (Exception e) {
}
}
}
3客户端
package sterning;
import javaioBufferedOutputStream;
import javaioDataInputStream;
import javaioDataOutputStream;
import javaioFileOutputStream;
public class ClientTest {
private ClientSocket cs = null;
private String ip = "localhost";// 设置成服务器IP
private int port = 8821;
private String sendMessage = "Windwos";
public ClientTest() {
try {
if (createConnection()) {
sendMessage();
getMessage();
}
} catch (Exception ex) {
exprintStackTrace();
}
}
private boolean createConnection() {
cs = new ClientSocket(ip, port);
try {
csCreateConnection();
Systemoutprint("连接服务器成功!" + "\n");
return true;
} catch (Exception e) {
Systemoutprint("连接服务器失败!" + "\n");
return false;
}
}
private void sendMessage() {
if (cs == null)
return;
try {
cssendMessage(sendMessage);
} catch (Exception e) {
Systemoutprint("发送消息失败!" + "\n");
}
}
private void getMessage() {
if (cs == null)
return;
DataInputStream inputStream = null;
try {
inputStream = csgetMessageStream();
} catch (Exception e) {
Systemoutprint("接收消息缓存错误\n");
return;
}
try {
//本地保存路径,文件名会自动从服务器端继承而来。
String savePath = "E:\\";
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];
int passedlen = 0;
long len=0;
savePath += inputStreamreadUTF();
DataOutputStream fileOut = new DataOutputStream(new BufferedOutputStream(newBufferedOutputStream(new FileOutputStream(savePath))));
len = inputStreamreadLong();
Systemoutprintln("文件的长度为:" + len + "\n");
Systemoutprintln("开始接收文件!" + "\n");
while (true) {
int read = 0;
if (inputStream != null) {
read = inputStreamread(buf);
}
passedlen += read;
if (read == -1) {
break;
}
//下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比
Systemoutprintln("文件接收了" + (passedlen 100/ len) + "%\n");
fileOutwrite(buf, 0, read);
}
Systemoutprintln("接收完成,文件存为" + savePath + "\n");
fileOutclose();
} catch (Exception e) {
Systemoutprintln("接收消息错误" + "\n");
return;
}
}
public static void main(String arg[]) {
new ClientTest();
}
}
一、HTTP请求(APACHE的HttpClient实现)
服务器端,就是普通的servlet、Strutus2就可以
移动端
protected static String get(String url, List<NameValuePair> params) {
String resultMsg;
// 设置http请求配置
HttpParams parms = new BasicHttpParams();
parmssetParameter("charset", HTTPUTF_8);
// 配置连接超时
HttpConnectionParamssetConnectionTimeout(parms, 10 1000);
// 设置请求超时
HttpConnectionParamssetSoTimeout(parms, 15 1000);
// 实例化HttpClient
HttpClient httpclient = new DefaultHttpClient(parms);
// 实例化HttpGet
HttpGet httpget = new HttpGet(url);
// 设置请求头
httpgetaddHeader("Content-Type", "application/json");
httpgetaddHeader("charset", HTTPUTF_8);
try {
if (paramssize() > 0)
url = url + "" + URLEncodedUtilsformat(params, HTTPUTF_8);
HttpResponse resp = httpclientexecute(httpget);
int statusCode = respgetStatusLine()getStatusCode();
if (statusCode == HttpStatusSC_OK) {
StringBuffer result = getResponse(resp);
resultMsg = resulttoString();
} else {
resultMsg = "连接异常";
}
} catch (Exception e) {
resultMsg = "连接异常";
} finally {
// 关闭get
httpgetabort();
// 关闭连接 ,释放资源
httpclientgetConnectionManager()shutdown();
}
return resultMsg;
}
protected static String post(String uri, Object params) {
String resultMsg;
// 设置http请求配置
HttpParams hp = new BasicHttpParams();
hpsetParameter("charset", HTTPUTF_8);
// 配置连接超时
HttpConnectionParamssetConnectionTimeout(hp, 10 1000);
HttpConnectionParamssetSoTimeout(hp, 15 1000);
// 实例化HttpClient
HttpClient httpclient = new DefaultHttpClient(hp);
// 实例化HttpPost请求
HttpPost httppost = new HttpPost(uri);
// 设置头信息
httppostaddHeader("Content-Type", "application/json");
httppostaddHeader("charset", HTTPUTF_8);
try {
// 将参数进行json化
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapperwriteValueAsString(params);
Logi(TAG, "URI=" + uri + ",BEAN=" + jsonStr);
// 定义消息实体
StringEntity se = new StringEntity(jsonStr, HTTPUTF_8);
httppostsetEntity(se);
// 通信
HttpResponse resp = httpclientexecute(httppost);
int statusCode = respgetStatusLine()getStatusCode();
Logi(TAG, "StatusCode=" + statusCode);
if (statusCode == HttpStatusSC_OK) {
StringBuffer result = getResponse(resp);
resultMsg = resulttoString();
} else {
resultMsg = "连接异常";
}
} catch (Exception e) {
eprintStackTrace();
resultMsg = "连接异常";
} finally {
// 关闭get
httppostabort();
// 关闭连接 ,释放资源
httpclientgetConnectionManager()shutdown();
}
Logi(TAG, resultMsg);
return resultMsg;
}
二、SOCKET连接
服务器端:
import javaioBufferedReader;
import javaioIOException;
import javaioInputStreamReader;
import javaioPrintWriter;
import javanetServerSocket;
import javanetSocket;
public class service_java_test {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(10000); //绑定的端口号
Socket socket = serveraccept(); //连接不成功以至于下一行的"连接成功"
//在调试区显示不出来
Systemoutprintln("连接成功");
BufferedReader in = new BufferedReader(new InputStreamReader(socketgetInputStream()));
PrintWriter out = new PrintWriter(socketgetOutputStream());
while (true) {
String msg = inreadLine();
Systemoutprintln(msg);
outprintln("Server received " + msg); //向接收方发送已接受到了的语句
outflush();
if (msgequals("bye")) { //若接收到"bye"则break
break;
}
}
socketclose();
}
}
安卓客户端:
package comexamplet4_android;
import javanetSocket;
import androidappActivity;
import androidosBundle;
import androidwidgetTextView;
public class MainActivity extends Activity {
private TextView myTextView;
protected void onCreate(Bundle savedInstanceState) {
superonCreate(savedInstanceState);
setContentView(Rlayoutactivity_main);
myTextView = (TextView) findViewById(RidtextView1);
Thread t = new Thread(new Runnable(){
public void run(){
try {
Socket sk = new Socket("1921682531", 10000);//绑定套接字,这一行一直执行不成功
//以至于下一行在安卓页面的TextView上
//不显示“已连接”的字样
//"1921682531"是我利用DOS命令查找
//的本机IP
myTextViewsetText("已连接");
} catch (Exception e) {
eprintStackTrace();
}
}
});
tstart();
}
}
0条评论