最近涉及了一些网络编程,在这里总结一下。
项目是一个多域仿真系统,模型简要说明下:局域网中有l台机器,代表l个域,每个域有n个节点,每个节点有m种资源每次仿真时,随机选一个节点申请某个资源,这个资源可能好几个域上都有节点拥有它。选择信誉值最高的节点作为服务者,与其进行交互。
对网络的要求是,可以将一个域上的东西发到另一个节点。最开始的想法是tcp开销较大且局域网丢包概率很小,因此考虑用简单快捷的UDP进行传输。UDP协议是无连接的协议,在JAVA中java.util.DatagramSocket负责接收和发送UDP数据报,Datagrampacket表示UDP数据报。DatagramSocket提供了接收和发送数据报的方法。
public void receive(DatagramPacket dst)throws IOException
public void send(DatagramPacket p)throws IOException
测试时发现会报异常,UDP规定每个包大小不能超过64K,而我们传送的数据至少几百KB。期间考虑过手工编号分组的方法,但没能成功。转而考虑TCP。
TCP中服务器程序监听端口,接收客户程序的连接请求。
ServerSocket server=new ServerSocket(8000);
用accpet()方法等待客户连接请求,这个方法是阻塞的,直到有客户连接才返回一个Socket对象
Socket socket=server.accept();
客户端用
Socket socket=new Socket(addr,port);
建立和server的连接。
项目采用TCP连接后可以正常传输数据了,但是由于仿真一次所需时间只要一、两秒钟时间,频繁创建socket导致程序不稳定。后经导师提醒,采用长连接的方法,即一个域初始化时,就与局域网中其他所有域建立tcp连接,这个连接建立后不关闭,因为每次仿真几乎都要传输数据。修改时碰到第一个问题是,以前accept方法是阻塞的,即需要发数据时客户端建立socket,服务端监听线程就收到一个请求,交与处理线程处理。现在socket保持连接,如何知道客户端要发送数据了呢?
直接说解决方法了。长连接是要把socket保存下来的,新建socket的同时,取得它的输出流,因为要发送对象,用ObjectOutputStream来装饰。
sendObjectStream = new ObjectOutputStream(sendSocket.getOutputStream());
要发送时,只要得到sendObjectStream ,调用writeObject即可。由于每个节点即可能是客户端也可能是服务端,每个域可能同时进行发送和接收,这时可以使用保存的这个socket接收,我是在新建这个socket时,就开一个接收线程,把这个socket传过去用于接收。
public class Receiver implements Runnable{
private Socket s = null;
private ObjectInputStream ois = null;
private static volatile boolean bConnected = false;
private Network network;
public Receiver(Socket s,Network n){
this.s = s;
this.network = n;
bConnected = true;
try {
ois = new ObjectInputStream(s.getInputStream());
} catch (IOException e) {
System.out.println("S关闭了");
e.printStackTrace();
}
}
public void run()
{
try
{
while(bConnected)
{
try
{
long begin = System.currentTimeMillis();
NetParameterPacket npp = (NetParameterPacket) ois.readObject();
long end = System.currentTimeMillis();
System.out.println("readObject用的时间为"+(end-begin)+"ms");
PacketHandle ph = new PacketHandle(npp,network,s);
new Thread(ph).start();
}
catch(EOFException e)
{
System.out.println("此时无数据");
try
{
Thread.sleep(500);
} catch (InterruptedException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
catch (IOException e)
{
e.printStackTrace();
if(e instanceof SocketException)
{
bConnected=false;
}
} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
finally
{
if(ois!=null){
try
{
ois.close();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
ois = null;
}
if(s!= null){
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
s = null;
}
}
}
public static void setBConnected(boolean connected)
{
bConnected = connected;
}
}
关于谁向谁新建TCP的问题:局域网中A域在运行时,这时B域申请加入。B域首先在局域网中广播,A域收到广播后进行响应,new一个socket向其建立tcp连接,并新建接收线程,将这个socket传过去用于接收。B域监听到这个tcp后,得到socket=server.accpet();新开一个接收线程的同时,将这个socket保存下来用于发送TCP。发送TCP代码为
public void sendTCPSingle(Object o , String address)
{
Domain d = getDomainByName(address);
if(d == null)
{
System.out.println("没找到该domain");
return;
}
try
{
sendLock.lock();
ObjectOutputStream oos = d.getSendObjectStream();
oos.writeObject(o);
oos.flush();
} catch (IOException e)
{
System.out.println("发送对象出错!");
//对发送异常进行处理
SocketAddress remoteAddr = new InetSocketAddress(address,TCP_PORT);
try
{
if(d.getSendSocket().isClosed())
{
Socket newSocket = new Socket(address,TCP_PORT);
System.out.println("socket已经关闭,重新向"+address+"发送建立TCP连接请求");
d.setSendSocket(newSocket);
}
else
d.getSendSocket().connect(remoteAddr);
}
catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
finally
{
sendLock.unlock();
}
}
其中Domain类表示域。
用加锁的原因是,某次交互可能两个线程同时准备发送,这时发送的一方会报异常
java.net.SocketException: Software caused connection abort: socket write error,接收方也跟着异常
java.io.StreamCorruptedException: invalid type code: 00
网上说长连接要用心跳方法检测对方是否还活着,这里因为是局域网且数据一直要传送,就没使用。
分享到:
相关推荐
6. 网络编程常见问题:Java网络编程中常见的问题包括网络连接问题、数据传输问题、网络安全问题等。Java程序员需要了解这些问题的解决方法和对策。 7. Java网络编程中的多线程:Java网络编程中多线程编程是指使用多...
Java网络编程是Java开发中的重要领域,它涵盖了网络应用程序的设计、实现和调试。在这个主题下,我们可以探讨多个关键知识点: 1. **Java Socket编程**:Java的Socket类提供了基于TCP/IP协议的网络通信能力。通过...
"Java网络编程实验报告" 本实验报告主要介绍了Java网络编程的基本概念和实现方法,通过设计和实现一个简单的客户端/服务器应用程序,了解Java网络编程的基本原理和实现方法。 知识点1:Java 网络编程基础 Java ...
《Java网络编程(第4版)》是一本深入探讨Java平台上的网络编程技术的专业书籍,适合想要提升Java通讯技术的学者阅读。此书全面覆盖了Java网络编程的基础和高级概念,帮助开发者理解如何利用Java语言构建高效、可靠的...
《Java网络编程(第四版)》是一本深入探讨Java在互联网环境下的编程技术的经典书籍。本书旨在帮助读者理解和掌握如何利用Java语言进行高效、安全的网络通信。书中内容覆盖了从基本的网络概念到复杂的多线程编程,是...
Java网络编程是计算机科学中的一个重要领域,特别是在软件开发中,它涉及到如何通过网络进行数据传输和通信。在Java中,网络编程主要依赖于Java的Socket编程、ServerSocket、URL类以及NIO(非阻塞I/O)等核心API。这...
在本资料中,《Java网络编程》第三版提供了深入浅出的讲解,旨在帮助开发者提升对这一领域的理解。 1. **基础概念**: - **网络模型**:Java网络编程基于OSI七层模型和TCP/IP四层模型。理解这些模型有助于理解网络...
Java网络编程是构建分布式应用程序的关键技术,特别是在服务器端开发中,多线程和连接池是其核心概念。本文将深入探讨这两个主题,并结合文件传输的实际应用进行讲解。 首先,我们来理解多线程。在Java中,多线程...
Java网络编程是开发分布式应用程序的关键技术,它使得Java程序能够与其他设备、系统和服务进行通信。本书《Java网络编程实例:Java网络编程实例》显然聚焦于通过实际案例来教授这一核心技能。以下是一些主要的知识点...
Java网络编程是开发...这个"java网络编程使用的简单例子"可能包含了以上提到的一些概念,通过实际的代码示例,可以帮助我们更好地理解和应用这些知识。学习和实践这些内容,将有助于开发高效、可靠的网络应用程序。
1. **Java网络编程基础**:首先,书中会介绍Java中的Socket编程,包括TCP和UDP协议的基础知识,以及如何使用Java的Socket和ServerSocket类创建客户端和服务器端的连接。 2. **I/O与NIO**:Java的I/O流系统是网络...
Java网络编程是开发分布式应用程序的关键技术,它允许程序通过网络发送和接收数据。《Java网络编程实例》这本书的源代码提供了丰富的示例,帮助读者深入理解这一领域。本压缩包包含的源代码覆盖了Java网络编程的各种...
《Java网络编程精解》是孙卫琴老师的一本经典教程,主要涵盖了Java语言在网络编程领域的深度解析。这本书深入浅出地介绍了如何使用Java进行网络通信,包括基本的TCP/IP协议、套接字编程、多线程技术以及HTTP、FTP等...
Java网络编程是开发分布式应用程序的关键技术,它允许Java程序与其他计算机进行通信,实现数据的交换。这份"Java网络编程资料"包含三个重要的学习资源:关于Socket套接字的"Java套接字编程.chm"、关于网络协议特别是...
《JAVA网络编程大全》是一本全面且深入介绍Java网络编程技术的权威著作,旨在帮助读者掌握Java在构建网络应用程序中的核心概念和实践技巧。PDF版的书籍为学习者提供了便捷的电子阅读体验,随时随地都能深化对Java...
Java网络编程是Java开发中的重要领域,它涵盖了网络通信的所有基本概念和技术,包括TCP/IP协议栈、套接字(Socket)编程、多线程、数据传输格式等。孙卫琴的《java网络编程》一书深入浅出地讲解了这些核心概念,并...
本资源为"Java网络编程.chm",是一本关于Java网络编程的电子书,以实例驱动的方式深入讲解了相关知识。 首先,我们要理解Java在网络编程中的基础——IO流。Java中的IO流分为字节流和字符流,它们用于读写数据,包括...
《Java网络编程》是编程领域的经典著作,尤其对于学习Java网络编程的初学者及进阶者来说,这本书具有很高的参考价值。它详细介绍了如何利用Java语言进行网络通信,涵盖了网络编程的基本概念、协议以及实现方法。 一...
总的来说,"java网络编程课件.zip"是一个全面的教程,可以帮助学习者从基础到进阶掌握Java网络编程的各个方面,包括TCP/IP通信、套接字编程、HTTP协议、多线程以及输入/输出流的使用。通过深入学习和实践,开发者...
2. **Java网络编程API**:深入解析Java的Socket编程,包括ServerSocket和Socket类的使用,以及如何创建基于TCP的套接字连接。同时,也会涉及DatagramSocket和MulticastSocket类,讲解UDP(用户数据报协议)的无连接...