您的位置:首页 > 理论基础 > 计算机网络

黑马程序员_王康java 网络编程

2012-02-27 09:16 411 查看
java 网络编程

1, Java Applet小应用程序基本结构

import java.applet.*;

import java.awt.*;

class  类名  extends Applet

{

类成员声明

}

Test.html 测试网页

<HTML>

<HEAD>

<TITLE>MyFirstJavaApplet</TITLE>

</HEAD>

<BODY>

<HR>

<APPLET CODE=MyFirstMyApplet WIDTH=500

HEIGHT=500>

</APPLET>

</BODY>

</HTML>

和网络编程有关的基本API位于java.net包中,该包中包含了基本的网络编程实现,

该包是网络编程的基础。该包中既包含基础的网络编程类,也包含封装后的专门处理WEB相关的处理类。

2,网络编程ip

首先来介绍一个基础的网络类——InetAddress类。该类的功能是代表一个IP地址,

并且将IP地址和域名相关的操作方法包含在该类的内部。

关于该类的使用,下面通过一个基础的代码示例演示该类的使用,代码如下:

package inetaddressdemo;

import java.net.*;

/**

* 演示InetAddress类的基本使用

*/

public class InetAddressDemo {

public static void main(String[] args) {

try{

//使用域名创建对象

InetAddress inet1 = InetAddress.getByName("www.fantao.com");

System.out.println(inet1);

//使用IP创建对象

InetAddress inet2 = InetAddress.getByName("127.0.0.1");

System.out.println(inet2);

//获得本机地址对象

InetAddress inet3 = InetAddress.getLocalHost();

System.out.println(inet3);

//获得对象中存储的域名

String host = inet3.getHostName();

System.out.println("域名:" + host);

//获得对象中存储的IP

String ip = inet3.getHostAddress();

System.out.println("IP:" + ip);

}catch(Exception e){}

}

}

3,网络编程Socket,tcp udp

在客户端网络编程中,首先需要建立连接,在Java API中以java.net.Socket类的对象代表网络连接,

所以建立客户端网络连接,也就是创建Socket类型的对象,该对象代表网络连接,示例如下:

Socket socket1 = new Socket(“192.168.1.100”,10000);

Socket socket2 = new Socket(“www. 35pingtai.com”,80);

上面的代码中,socket1实现的是连接到IP地址是192.168.1.103的计算机的10000号端口,

而socket2实现的是连接到域名是www.35pingtai.com的计算机的80号端口,至于底层网络如何实现建立连接,对于程序员来说是完全透明的。

OutputStream os = socket1.getOutputStream(); //获得输出流

InputStream is = socket1.getInputStream(); //获得输入流

上面的代码中,分别从socket1这个连接对象获得了输出流和输入流对象,在整个网络编程中,后续的数据交换就变成了IO操作,

也就是遵循“请求-响应”模型的规定,先向输出流中写入数据,这些数据会被系统发送出去,然后在从输入流中读取服务器端

的反馈信息,这样就完成了一次数据交换过程,当然这个数据交换过程可以多次进行。

最后当数据交换完成以后,关闭网络连接,释放网络连接占用的系统端口和内存等资源,完成网络操作,示例代码如下:

socket1.close();

这就是最基本的网络编程功能介绍。下面是一个简单的网络客户端程序示例,该程序的作用是向服务器端发送一个字符串“Hello”,并将服务器端的反馈显示到控制台,数据交换只进行一次,当数据交换进行完成以后关闭网络连接,程序结束。实现的代码如下:

例子:

package tcp;

import java.io.*;

import java.net.*;

/**

* 简单的Socket客户端

* 功能为:发送字符串“Hello”到服务器端,并打印出服务器端的反馈

*/

public class SimpleSocketClient {

public static void main(String[] args) {

Socket socket = null;

InputStream is = null;

OutputStream os = null;

//服务器端IP地址

String serverIP = "127.0.0.1";

//服务器端端口号

int port = 10000;

//发送内容

String data = "Hello";

try {

//建立连接

socket = new Socket(serverIP,port);

//发送数据

os = socket.getOutputStream();

os.write(data.getBytes());

//接收数据

is = socket.getInputStream();

byte[] b = new byte[1024];

int n = is.read(b);

//输出反馈数据

System.out.println("服务器反馈:" + new String(b,0,n));

} catch (Exception e) {

e.printStackTrace(); //打印异常信息

}finally{

try {

//关闭流和连接

is.close();

os.close();

socket.close();

} catch (Exception e2) {}

}

}

}

如果需要在控制台下面编译和运行该代码,需要首先在控制台下切换到源代码所在的目录,然后依次输入编译和运行命令:

javac –d . SimpleSocketClient.java

java tcp.SimpleSocketClient

和下面将要介绍的SimpleSocketServer服务器端组合运行时,程序的输出结果为:

服务器反馈:Hello

在服务器端程序编程中,由于服务器端实现的是被动等待连接,所以服务器端编程的第一个步骤是监听端口,

也就是监听是否有客户端连接到达。实现服务器端监听的代码为:

ServerSocket ss = new ServerSocket(10000);

通过获得连接,使得客户端的连接在服务器端获得了保持,另外使得服务器端的端口释放出来,

可以继续等待其它的客户端连接。 实现获得连接的代码是:

Socket socket = ss.accept();

最后,在服务器端通信完成以后,关闭服务器端连接。实现的代码为:

ss.close();

例子: package tcp;

import java.io.*;

import java.net.*;

/**

* 功能:将客户端发送的内容反馈给客户端

*/

public class SimpleSocketServer {

public static void main(String[] args) {

ServerSocket serverSocket = null;

Socket socket = null;

OutputStream os = null;

InputStream is = null;

//监听端口号

int port = 10000;

try {

//建立连接

serverSocket = new ServerSocket(port);

//获得连接

socket = serverSocket.accept();

//接收客户端发送内容

is = socket.getInputStream();

byte[] b = new byte[1024];

int n = is.read(b);

//输出

System.out.println("客户端发送内容为:" + new String(b,0,n));

//向客户端发送反馈内容

os = socket.getOutputStream();

os.write(b, 0, n);

} catch (Exception e) {

e.printStackTrace();

}finally{

try{

//关闭流和连接

os.close();

is.close();

socket.close();

serverSocket.close();

}catch(Exception e){}

}

}

}

实现该逻辑的服务器端程序代码如下:

package udp;

import java.net.*;

/**

* 可以并发处理数据包的服务器端

* 功能为:显示客户端发送的内容,并向客户端反馈字符串“OK”

*/

public class MulUDPServer {

public static void main(String[] args) {

DatagramSocket ds = null; //连接对象

DatagramPacket receiveDp; //接收数据包对象

final int PORT = 10012; //端口

byte[] b = new byte[1024];

receiveDp = new DatagramPacket(b,b.length);

try{

//建立连接,监听端口

ds = new DatagramSocket(PORT);

System.out.println("服务器端已启动:");

while(true){

//接收

ds.receive(receiveDp);

//启动线程处理数据包

new LogicThread(ds,receiveDp);

}

}catch(Exception e){

e.printStackTrace();

}finally{

try{

//关闭连接

ds.close();

}catch(Exception e){}

}

}

}

该代码实现了服务器端的接收逻辑,使用一个循环来接收客户端发送过来的数据包,当接收到数据包以后启动一个LogicThread线程处理该数据包。

这样服务器端就可以实现同时处理多个数据包了。

实现逻辑处理的线程代码如下:

package udp;

import java.net.*;

/**

* 逻辑处理线程

*/

public class LogicThread extends Thread {

/**连接对象*/

DatagramSocket ds;

/**接收到的数据包*/

DatagramPacket dp;

public LogicThread(DatagramSocket ds,DatagramPacket dp){

this.ds = ds;

this.dp = dp;

start(); //启动线程

}

public void run(){

try{

//获得缓冲数组

byte[] data = dp.getData();

//获得有效数据长度

int len = dp.getLength();

//客户端IP

InetAddress clientAddress = dp.getAddress();

//客户端端口

int clientPort = dp.getPort();

//输出

System.out.println("客户端IP:" + clientAddress.getHostAddress());

System.out.println("客户端端口号:" + clientPort);

System.out.println("客户端发送内容:" + new String(data,0,len));

//反馈到客户端

byte[] b = "OK".getBytes();

DatagramPacket sendDp = new DatagramPacket(b,b.length,clientAddress,clientPort);

//发送

ds.send(sendDp);

}catch(Exception e){

e.printStackTrace();

}

}

}

在该线程中,只处理一次UDP通讯,当通讯结束以后线程死亡,在线程内部,每次获得客户端发送过来的信息,将获得的信息输出到服务器端程序的控制台,然后向客户端反馈字符串“OK”。

由于UDP数据传输过程中可能存在丢失,所以在运行该程序时可能会出现程序阻塞的情况。如果需要避免该问题,可以将客户端的网络发送部分也修改成线程实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: