今天看了一天的网络编程,感觉网络编程 就是计算机之间的IO操作。前面说的IO是单个计算机之间程序之间的通讯,而网络编程则是在多个计算机之间的程序的通讯。
大致梳理一下整个过程:计算机客户端通过IP唯一定位一个服务器主机,通过端口号在该主机上唯一定位一个程序,建立连接后,两个计算机就可以进行通讯,这就是基本上的IO操作了。我们说通讯的要素:
- IP和端口号(合成Socket):IP对应的类:InetAddress类
- 网络通讯协议:包括TCP和UDP两个。
本篇主要包括InetAddress类,TCP/IP协议,UDP协议,URL通讯等主要内容。
InetAddress:
IP可以唯一定位一个计算机。在java程序中,InetAddress类则定义ip地址的类。类似于IO操作的File类作用。大致操作如下:
/*
* 一个InetAddress对象代表一个ip
* InetAddress.getByName获得一个ip,可以用ip和域名
* getHostName()获取域名,getHostAddress()地址
*/
InetAddress address_1=InetAddress.getByName("www.sougou.com");
System.out.println(address_1);
System.out.println(address_1.getHostName());
System.out.println(address_1.getHostAddress());
TCP/IP:
安全的通讯协议。必须建立连接实现三次握手方可通讯。效率较低
大致的代码实现步骤:
- 创建socket
- 创建输出输出流
- 实现输入输出操作
- 关闭流
@Test
public void clinet()
{
Socket s=null;
FileInputStream fis=null;
InputStream is=null;
OutputStream os=null;
try {
//1创建socket
s=new Socket(InetAddress.getByName("127.0.0.1"), 9989);
//2从本地获取文件发送给服务器
fis=new FileInputStream(new File("01.jpg"));
is=s.getInputStream();
os=s.getOutputStream();
byte[] b=new byte[1024];
int len;
while((len=fis.read(b))!=-1)
{
os.write(b, 0, len);
}
s.shutdownOutput();
//3获取服务器发送的数据
while((len=is.read(b))!=-1)
{
String sd=new String(b, 0, len);
System.out.print(sd);
}
} catch (IOException e) {
e.printStackTrace();
}
finally
{
//4关闭各种流
if(os!=null)
{
try {
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fis!=null)
{
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(s!=null)
{
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@Test
public void server()
{
ServerSocket ss=null;
Socket s=null;
InputStream is=null;
FileOutputStream fos=null;
OutputStream os=null;
try {
//创建socket
ss=new ServerSocket(9989);
s=ss.accept();
//从客户端获取文件并保存在本地
is=s.getInputStream();
os=s.getOutputStream();
fos=new FileOutputStream(new File("02.jpg"));
byte[] b=new byte[1024];
int len;
while((len=is.read(b))!=-1)
{
fos.write(b, 0, len);
}
//发送状态数据
os.write("发送成功".getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
//关闭各种流
if(os!=null)
{
try {
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fos!=null)
{
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(is!=null)
{
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(s!=null)
{
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ss!=null)
{
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
UDP:
与TCP稍微不同,这个不需要开始就建立连接。UDP协议使用两个类,一个是DatagramSocket来建立socket,还用一个DatagramPacket类封装需要发送的数据,发送的目标ip和端口还有客户端自己的信息等。不需要建立,每个数据报不能大于64K,很多个数据报共同组成一个文件。效率较快。
这里简单的通过向服务器发送一个字符串来说明整个流程:
@Test
public void send()
{
DatagramSocket ds=null;
try {
ds=new DatagramSocket();
byte[] b="this is Qingdao hotel".getBytes();
DatagramPacket pack=new DatagramPacket(b, b.length, InetAddress.getByName("127.0.0.1"), 9989);
ds.send(pack);
} catch (IOException e) {
e.printStackTrace();
}
finally
{
if(ds!=null)
{
ds.close();
}
}
}
@Test
public void receive()
{
DatagramSocket ds=null;
try {
ds=new DatagramSocket(9989);
byte[] b=new byte[1024];
DatagramPacket pack=new DatagramPacket(b, 0, b.length);
ds.receive(pack);
String sk=new String(pack.getData(),0,pack.getLength());
System.out.println(sk);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
if(ds!=null)
{
ds.close();
}
}
}
URL编程:
统一资源定位符,表示因特网上唯一的资源地址。
基本结构由5部分组成:
<传输协议>://<主机名>:<端口号>/<文件名>
例如:
http://
localhost:88888/helloworld/index.jsp
在java中URL对应的一个URL类,该类位于.net包下。使用URL编程主要分为只读和可读可写两个方面。只读的可以用url.openStream来实现对文件的读操作,读写都有的话,则要使用 URLConnection类。这里用 URLConnection类来实现对服务器资源的读写(大致下载就是这个原理吧):
@Test
public void UURTest()
{
URL url=null;
InputStream is=null;
FileOutputStream fos= null;
URLConnection urlConn=null;
try {
url=new URL("http://localhost:8888/struts2/01.jpg");
urlConn=url.openConnection();
is=urlConn.getInputStream();
fos=new FileOutputStream("003.jpg");
byte[] b=new byte[200];
int len;
while((len=is.read(b))!=-1)
{
fos.write(b, 0, len);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
if(fos!=null)
{
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(is!=null)
{
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fos!=null)
{
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
好了,大致的网络编程主要就这几个方面。我画了一个图: