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

黑马程序员——Java基础—网络编程

2015-06-05 11:01 801 查看
——- android培训java培训、期待与您交流! ———-

一、网络模型

OSI模型(七层):物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。

TCP/IP模型(四层):物理层、网际层(IP)、传输层(TCP、UDP协议)、应用层(HTTP、FTP协议)。

二、网络通讯三要素

1、IP地址:网络中设备的唯一标识,java中描述IP的类是:InetAddreess。获取本机的主机:InetAddress i = InetAddress.getLoclHost();获取任一主机:InetAddress i = InetAddress.getByName(“192.168.2.56”);

2、端口:端口是用4为数字表示的。常用的端口:SVN-3690,Tomacat-8080,Apache-80,mySQL-3306。

3、传输协议:常用的是TCP和UDP。

三、TCP、UDP

(一)、UDP

  1、UDP的特点:面向无连接,数据要封包,且不能大于64k,因为无连接,所以不可靠,但是效率快。使用UDP协议传输的应用程序:QQ、桌面共享、网络会议等。

  2、UDP传输:建立发送端、接收端,将数据打包,从发送端用send方法将数据包发送出去,接收端通过reveive方法将数据包接收到已定义好的数据包中,并用数据包的方法解析数据。关闭Socket服务。发送端和接收端是两个独立的运行程序。相关的类:DatagramSocketDatagramPacket

  3、建立UDP发送端服务的步骤:

    (1)、用DatagramSocket建立发送端Socket服务;

    (2)、确定要发送的数据,并用DatagramPacket将数据打包;

    (3)、用DatagramSocket里的send方法将数据包发送出去;

    (4)、关闭Socket服务。

  4、建立UDP接收端服务的步骤:

    (1)、用DatagramSocket建立接收端的Socket服务;

    (2)、用DatagramPacket创建一个数据包;

    (3)、用DatagramSocket中的receive方法接收数据包,并将数据包存放在已定义好的数据包中。

    (4)、用DatagramPacket方法解析数据;

    (5)、关闭接收端Socket服务。

  5、模拟聊天功能

/*
聊天功能模拟。
分析:
聊天,既能发送信息,也能接收信息,两者同时进行,所以该用两个线程来实现;

步骤:
1、描述发送端,并实现Runnable接口;
2、复写run方法。
3、用Thread建立线程;
4、将Runnable的子类对象传递给Thread的构造函数;

其他说明:
接收端没接收端消息,先看看消息是否发送出去了。
*/
import java.net.*;
import java.io.*;
//建立发送端
class ChatSend implements Runnable
{
private DatagramSocket ds;
ChatSend(DatagramSocket ds)
{
this.ds = ds;
}
public void run()
{
BufferedReader bufr = null;
DatagramPacket dp = null;
try
{
//获取键盘录入对象
bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line = bufr.readLine()) != null)
{
//信息是以字节形式发送,所以需要将字符转字节
byte[] buf = line.getBytes();
//将数据打包
dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.75.1"),8887);
//将数据包发送出去
ds.send(dp);
//判断聊天结束标志
if(line.equals("goodbye"))
{
//System.out.println(line+"聊天结束!");
break;
}
}
}
catch (IOException e)
{
throw new RuntimeException("发送数据失败!");
}
finally
{
if(bufr != null)
{
try
{
bufr.close();
}
catch (IOException ie)
{
}
}
}
}
}
//建立接收端
class ChatReceive implements Runnable
{
private DatagramSocket ds;
ChatReceive(DatagramSocket ds)
{
this.ds = ds;
}
public void run()
{
try
{
while(true)
{
//建立数据包,用于接收发送端发送过来的数据
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
//用数据包方法解析数据
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
//判断发送端是否结束聊天
if(data.equals("goodbye"))
{
System.out.println("发送端结束聊天!");
break;
}
System.out.println(ip+"---"+data);
}
}
catch (IOException e)
{
throw new RuntimeException("数据接收失败!");
}
}
}
class ChatTest
{
public static void main(String[] args)
{
try
{
//用Tread建立线程,开启并执行进程
new Thread(new ChatSend(new DatagramSocket())).start();
new Thread(new ChatReceive(new DatagramSocket(8887))).start();
}
catch (IOException e)
{
throw new RuntimeException("建立聊天失败!");
}

}
}


(二)、TCP

  1、TCP的特点:面向连接,两者之间建立通讯通道,可在通道中进行大数据传输,安全可靠,但效率稍低。比如:下载。

  2、TCP传输:建立客户端,并与服务器端建立连接,获取客户端的输出流将数据发生到服务器端,服务器端通过获取连接到该服务器上的客户端的读取流,获取客户端发送过来的信息,并用获取到的客户端的输出流将客户端需要的数据反馈给客户端。涉及的类:客户端:Socket,服务器端:ServerSocket。

  3、建立客户端的步骤:

    (1)、通过Socket建立客户端服务,并指定要连接的主机和端口;

    (2)、获取输出流;

    (3)、用输出流将数据传送到服务器;

    (4)、关闭Socket服务;

  4、建立服务器端的步骤:

    (1)、通过ServerSocket建立服务端服务;

    (2)、获取连接到服务器的客户端;

    (3)、通过获取到的客户端的读取流,读取客户端发送过来的信息;

    (4)、关闭Socket服务(可选)。

  5、模拟并发图片上传

/*
客户端并发上传照片。
分析:客户端并发上传照片,要求服务端可以处理多个客户端的请求。

主义事项:客户端端将图片信息发送结束,需要告诉服务端,数据已经发送结束,
不然服务端在读取数据时读取不到结束标志。
*/
import java.net.*;
import java.io.*;
class TcpPic
{
public static void main(String[] args)
{
Socket s = null;
FileInputStream ips = null;
OutputStream out = null;
InputStream in = null;
try
{
//建立客户端Socket服务,并指定要连接的主机
s = new Socket("192.168.75.1",10000);
//指定要上传的图片
ips = new FileInputStream("ibeacon-01_05.png");
//获取网络流中的输出流,用于向服务端发送数据
out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
//读一次硬盘的图片信息,想服务端发送一次
while((len = ips.read(buf)) != -1)
{
out.write(buf,0,len);
}
//告诉服务端已经上传完
s.shutdownOutput();

//获取服务端返回的数据
in = s.getInputStream();
byte[] bt = new byte[1024];
int lenth = in.read(bt);
System.out.println(new String(bt,0,lenth));

s.close();
}
catch (IOException e)
{
throw new RuntimeException("数据发送失败!");
}
finally
{
if(ips != null)
{
try
{
ips.close();
}
catch (IOException ie)
{
}
}
}
}
}
//定义服务端
class ServerPic implements Runnable
{
private Socket s;
ServerPic(Socket s)
{
this.s = s;
}
public void run()
{
InputStream in = null;
FileOutputStream ops = null;
OutputStream out = null;
try
{
//通过连接到服务端的客户端对象获取输入流
in = s.getInputStream();
//获取该客户机的IP
String path = s.getInetAddress().getHostAddress();
int count = 0;
File f = new File(path+"("+count+").png");
//将文件名封装成File对象,以便判断文件名是否重复
while(f.exists())
f = new File(path+"("+(count++)+").png");
//获取将图片信息写到硬盘的输出流
ops = new FileOutputStream(f);
//获取将信息返回给客户端的输出流
out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
//一边读取客户端发送过来的数据,一边将数据写到硬盘中
while((len = in.read(buf)) != -1)
{
ops.write(buf,0,len);
}

//给客户端返回信息
out.write("上传成功!".getBytes());
//System.out.println("商城成功");

s.close();
}
catch (IOException e)
{
System.out.println(e.toString());
throw new RuntimeException("图片接收失败!");
}
finally
{
if(ops != null)
{
try
{
ops.close();
}
catch (IOException ie)
{
}
}
}
}
}
class TcpPicTest
{
public static void main(String[] args)
{
ServerSocket ss = null;
Socket s = null;
try
{
//建立服务端Socket服务
ss = new ServerSocket(10000);
//获取连接到该服务端的客户端,并将其封装到一个线程中。
while(true)
{
s = ss.accept();
//创建线程,开启并执行线程代码
new Thread(new ServerPic(s)).start();
}
}
catch (IOException e)
{
throw new RuntimeException("服务端Socket建立失败!");
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: