黑马程序员 Java自学总结十六 网络编程
2013-08-09 15:21
555 查看
------ ASP.Net+Android+IO开发.Net培训期待与您交流! ------
总结内容来源于黑马毕老师的java基础教学视频
网络编程:
为了实现不同主机之间的数据传输和通信 。
网络模型:
OSI模型:从顶到底层 分别是: 应用层,表示层,会话层,传输层,网络层,数据链路层,物理层,分七层;
TCP/IP模型:它由应用层,传输层,网际层,网络接入组成;
FTP,HTTP都在应用层,TCP,UDP在传输层,IP在网际层。
网络通讯的三个要素:
1.IP地址:是主机在网络上的地址,在网上的唯一标识,127.0.0.1是本地回环地址,可测试网卡是否损坏;
2.端口号:数据要发送到对方指定的应用程序上,为了标识这些应用程序,用数字对其标识,这些数字就是端 口,或被称为逻辑端口;它并无物理实体与之对应;有效端口号从0~65535,其中0~1024是系统保留的 端口号;
一些常见的端口:浏览器:80 ; tomcat服务器:8080; mysql:3306;
3.传输协议:要完成传输,还要遵守相同的通信协议,国际通用协议是 TCP/IP协议,既能用于局域网,也可用于广域网,除了TCP/IP,还有 UDP,FTP,HTTP等协议;
数据封包:数据从应用层开始,每经一层,都加入该层的标识信息,直到物理层,这个过程叫数据封包,之后 变成二进制数据从物理设备上输出;
数据拆包:去掉每层的标识信息,获取数据的过程就是拆包过程;
网络编程现阶段主要是在网际层,传输层,而javaweb开发主要是在应用层;
java中对各个层都创建了对象与之对应,以方便我们开发使用;
IP地址:是数字,由四段组成,如192.168.1.1,使用时不便于记忆,所以有与之对应的主机名,主机名与IP地址相对应;IP常用的方法如下:都在java。net包中;
InetAddress: getLocalHost();可获取主机名和本地地址;
getHostAddress():主机地址的字符串表现形式;
getHostName():获取主机名称;
如果网络获取主机名称,可能出现解析不成功的情况,那么IP地址就是主机名,getByName("")可通过给定主机名,获取主机的IP地址;
代码:
[java] view
plaincopy
//IP协议类InetAddress
import java.net.*;
import java.util.*;
class InetAddressDemo
{
public static void main(String[] args) throws Exception
{
InetAddress i = InetAddress.getLocalHost();
System.out.println(i.toString());
InetAddress[] ia = InetAddress.getAllByName("www.baidu.com");
System.out.println(Arrays.asList(ia));
}
}
TCP和UDP协议:两者都在传输层;
两者的区别:
1.UDP:(User Datagram Protocol),用户数据报协议,是一种面向无连接的不可靠协议,它将数据源和目的封装成数据报包,在不需要建立连接的情况下就可实现传输,每个数据报包大小限制在64K内,特点是传输速度快;存在数据丢失的可能,主要应用于即时数据的传输,如QQ聊天程序,对话机,网络视频会议等;
2.TCP:(Transmission Control Protocol),传输控制协议,它是面向连接的可靠的传输协议,通过三次握手的形式完成数据传输通道的连接,传输大量的数据,特点是速度相对较慢,适合对数据完整性要求高的程序,如下载应用程序;
Socket:(插座,套接字):
网络编程其实就是socket编程,它是为网络服务的一种机制,每个应用程序都有一个socket通信端点,可以把socket想象为每个应用程序的插座,通信的两端都有socket,数据在两个socket之间通过IO传输;
UDP传输:UDP两端是发送端和接受端;
DatagramSocekt:UDP传输专用的程序通信断电,既能发送也能接受;
DatagramPacket: 数据报包,封装了UDP传输的数据报包,里面可以设置发送目的地的IP地址,端口和内容;
广播地址:每个网段尾数为255的IP 地址,如192.168.1.255就是一个广播地址;
UDP协议类及其使用
[java] view
plaincopy
import java.net.*;
import java.io.*;
/*
需求:通过udp传输方式,将一段文字数据发送出去
思路:
1.建立udpsochet服务.
2.提供数据,并将数据封装到数据包中.
3.通过soket服务发送功能,将数据发出去.
*/
class UdpSend
{
public static void main(String[] args) throws Exception
{
//1.创建udp服务,通过DatagramSocket对象.
DatagramSocket ds = new DatagramSocket(8888);
//2.确定数据,并封装成数据包.
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line=br.readLine())!=null)
{
byte[] buf = line.getBytes();
DatagramPacket dp =
new DatagramPacket(buf,buf.length,InetAddress.getByName(""),10000);
//3通过soket服务,将已有的数据包发送出去.通过send方法.
ds.send(dp);
if ("over".equals(line))
break;
}
//4.关闭资源
ds.close();
}
}
/*
需求:
定义一个应用程序,用于接收udp协议传输并处理.
思路:
1.定义udpsocket服务.通常会监听一个端口,其实就是给这个接收端定义数字标识
方便于明确哪些数据过来该应用程序可以处理.
2.定义一个数据包,因为要存储接收到的字节数据,
数据包对象中有更多功能可以提取字节数据中不同数据信息.
3.通过socket服务的receive方法将收到数据存入已定义好的数据包中.
4.通过数据包对象的特有功能,将这些不同数据取出.打印在控制台上.
5.关闭资源
*/
class UdpReceive
{
public static void main(String[] args) throws Exception
{
//1.创建udpsocket,建立端点
DatagramSocket ds = new DatagramSocket(10000);
//可以达到重复接收数据的目的
while(true)
{
//2.定义数据包,用于存储数据.
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,1024);
//3.通过服务的receive方法将收到的数据存入到数据包中.
ds.receive(dp);
//4.通过数据包的方法获取其中的数据.
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println(ip+"::"+data+"::"+port);
//5.关闭资源
//ds.close();
}
}
}
UDP协议编写聊天程序
[java] view
plaincopy
/*
知识点:
UDP协议, 线程, IO
编写一个聊天程序
收数据和发数据需要同时执行,那就需要用到多线程技术.
一个线程控制收,一个线程控制发.
因为收和发动作是不一致的,所以要定义两个run方法,
而且这两个方法要封装到不同类中.
*/
import java.net.*;
import java.io.*;
class Send implements Runnable
{
private DatagramSocket ds;
Send(DatagramSocket ds)
{
this.ds = ds;
}
public void run()
{
try
{
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line=br.readLine())!=null)
{
if("over".equals(line))
System.exit(0);
byte[] buf = line.getBytes();
DatagramPacket dp =
new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10005);
//将定义好的数据包发送到指定主机的指定端口
ds.send(dp);
}
}
catch (Exception e)
{
throw new RuntimeException("发送端失败");
}
}
}
class Rece implements Runnable
{
private DatagramSocket ds;
Rece(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());
System.out.println(ip+".."+data);
}
}
catch (Exception e)
{
throw new RuntimeException("发送端失败");
}
}
}
class CharTest
{
public static void main(String[] args) throws Exception
{
DatagramSocket sendSocket = new DatagramSocket();
DatagramSocket receSocket = new DatagramSocket(10005);
new Thread(new Send(sendSocket)).start();
new Thread(new Rece(receSocket)).start();
}
}
TCP传输:对应的是客户端和服务端
Socket:TCP传输客户端通信端点;
ServerSocket: TCP传输服务端端点;serversocket(port,backlog)这个构造函数中的backlog用于指定客户端的最大连接数;
因为TCP需要建立连接,所以socket客户端一建立就要指定服务端的IP和端口,而在服务端建立时,要设置监听的端口,TCP连接成功后,在客户端和服务端就会产生网络流,客户端提供对网络流进行读写的输入流和输出流对象,服务端操作网络流时,先获取客户端的socket对象,然后利用该socket的字节输入输出流进行读写操作,客户端和服务端进行多次交互时,注意阻塞式方法对程序的影响;
TCP代码演示一:
演示TCP传输。
1.tcp分客户端和服务端。
2.客户端对应的对象是Socket。
服务端对应的对象是SeverSocket
TCP协议及其使用
[java] view
plaincopy
/*
演示tcp传输.
1.tcp分客户端和服务端.
2.客户端对应的对象是Socket.
服务端对应的对象是ServerSocket.
客户端:
通过查阅socket对象,发现该对象建立时,就可以去连接主机.
因为tcp是面向连接的.所以在建立socket服务时,
就要有服务端存在.并连接成功.形成通路后,在该通道进行数据传输.
需求:给服务端发送一个文本数据.
步骤:
1.创建socket服务.并指定要连接的主机和端口.
2.获取socket中的输出流,在流中写入数据.
*/
import java.net.*;
import java.io.*;
class TcpClient
{
public static void main(String[] args) throws Exception
{
//创建客户端socket服务.指定目的主机和端口
Socket s = new Socket("LocalHost",10001);
//为了发送数据,应该获取socket中的输出流.
OutputStream out = s.getOutputStream();
out.write("tcp is coming".getBytes());
s.close();
}
}
/*
需求:定义端点接收数据并打印在控制台上.
服务端:
1.建立服务端的socket服务.ServerSocket();并监听一个端口
2.获取连接过来的客户端对象.通过 ServerSocket的accept方法,这个方法是阻塞的.
3.客户端如果发过来数据,那么服务端要使用对应的客户端对象,
并获取到该客户端对象的读取流来读取发过来的数据.
4.关闭服务端.(可选)
*/
class TcpServer
{
public static void main(String[] args) throws Exception
{
//建立服务端socket服务.并监听一个端口
ServerSocket ss = new ServerSocket(10001);
//通过accept方法获取连接过来的客户端对象
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"....connected");
//获取客户端发送过来的数据,使用客户端对象的读取流
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
s.close();
ss.close();
}
}
TCP协议的客户端和服务端互访
[java] view
plaincopy
/*
演示tcp传输的客户端和服务端的互访.
需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息.
*/
/*
客户端:
1.建立socket服务,指定要连接的主机和端口
2.获取输出流,将数据写入,通过网络发送给服务端.
3.获取输入流,将服务端反馈的数据获取到并打印
4.关闭客户端资源.
*/
import java.io.*;
import java.net.*;
class TcpClient2
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("LocalHost",10002);
OutputStream out = s.getOutputStream();
out.write("hello server".getBytes());
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
}
}
class TcpServer2
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10002);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+".....connected");
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
OutputStream out = s.getOutputStream();
out.write("received,hello client".getBytes());
}
}
TCP协议练习
[java] view
plaincopy
/*
需求:建立一个文本转换服务器.
客户端给服务端发送文本,服务端会将文本转成大写在返回客户端.
而且客户端可以不断的进行文本转换.当客户端输入over时,转换结束.
分析:
客户端:
既然是操作设备上的数据,那么可以使用io技术,并按照io操作规律思考.
源,键盘录入.
目的:网络设备,网络输出流.
而且操作的是文本数据.可以选择字符流.
步骤
1.建立服务.
2.获取键盘录入.
3.将数据发给服务端.
4.获取服务端返回的大写数据.
5.关闭资源.
都是文本数据,可以使用字符流进行操作,同时提高效率,加入缓冲.
*/
import java.io.*;
import java.net.*;
class TransClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("localhost",10010);
//定义键盘录入的字符流
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
//获取socket的输出流并转成字符输出流,发给服务端
OutputStreamWriter osw = new OutputStreamWriter(s.getOutputStream());
BufferedWriter bwout = new BufferedWriter(osw);
//定义一个socket读取流,读取服务端返回的大写信息.
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while ((line=br.readLine())!=null)
{
if(line.equals("over"))
break;
bwout.write(line);
bwout.newLine();
bwout.flush();
//服务端返回的数据
String str = brin.readLine();
System.out.println("server......"+str.toUpperCase());
}
s.close();
br.close();
}
}
/*
服务端:
源:socket读取流
目的:socket输出流
都是字符,用字符流
*/
class TransServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10010);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"........connected");
//读取socket读取流中的数据
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
//获取socket输出流,将大写数据写道输出流中,发给客户端
BufferedWriter bwout =
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while ((line=brin.readLine())!=null)
{
System.out.println(line);
if(line.equals("over"))
break;
bwout.write(line);
bwout.newLine();
bwout.flush();
}
s.close();
}
}
/*
该例子出现的问题.
现象:客服端和服务端都在莫名的等待.
为什么呢?
因为客户端和服务端都有阻塞式方法,这些方法没读到结束标记,
那么就导致两端都在等待.
*/
TCP协议--上传TXT文件
[java] view
plaincopy
//需求:用Tcp协议复制txt文件,从客户端上传到服务端
/*
客户端:
分析.
操作硬盘上的文件用到io流,
源:硬盘
目的:网络输出流
操作的文本文件,可以用字符流
步骤.
1.建立一个socket服务
2.获取txt文件内容
3.将数据发给服务端
4.接收服务端返回的信息
5.关闭资源
*/
import java.io.*;
import java.net.*;
class TextClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("192.168.1.250",10100);
//定义一个读取字符流缓冲区
BufferedReader br = new BufferedReader(new FileReader("tcp.txt"));
//获取socket输出流,把读取流中的数据写到socket输出流
BufferedWriter bwout =
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//获取socket输入流,接收服务端返回的数据
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while ((line=br.readLine())!=null)
{
bwout.write(line);
bwout.newLine();
bwout.flush();
}
s.shutdownOutput();
String str = brin.readLine();
System.out.println(str);
s.close();
br.close();
}
}
/*
服务端:
分析.
接收socket输入流数据,
源:网络输入流
目的:硬盘
操作的文本文件,可以用字符流
步骤.
1.建立一个socket服务
2.获取socket输入流中的数据
3.将数据用文件输出流写道txt文件中
4.给客户端发送已成功信息
5.关闭资源
*/
class TextServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10100);
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress()+"...connected");
//获取socket输入流,接收客户端发来的数据
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
//定义一个文件输出流缓冲区
BufferedWriter bw = new BufferedWriter(new FileWriter("tcp-2.txt"));
//获取socket输出流,把数据通过socket输出流返回给客户端
BufferedWriter bwout =
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while ((line=brin.readLine())!=null)
{
bw.write(line);
bw.newLine();
bw.flush();
}
bwout.write("文件上传成功");
bwout.close();
s.close();
bw.close();
}
}
TCP协议--上传图片文件
[java] view
plaincopy
//需求:客户端上传图片到服务端
/*
客户端.
1.创建端点socket.
2.用文件输入流获取图片文件数据.
3.用socket输出流将数据上传给服务端.
4.接收服务端返回的socket输入流.
5.关闭资源.
*/
import java.io.*;
import java.net.*;
class PicClient
{
public static void main(String[] args) throws Exception
{
//1.创建端点
Socket s = new Socket("192.168.1.250",10008);
//2.获取图片数据
FileInputStream fis = new FileInputStream("a.jpg");
//3.获取socket输出流,把数据发送到服务端
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int num = 0;
while ((num=fis.read(buf))!=-1)
{
out.write(buf,0,num);
}
//为socket输出流做标记,数据已发送完,结束阻塞
s.shutdownOutput();
//4.接收服务端返回的数据
InputStream in = s.getInputStream();
byte[] bys = new byte[1024];
int len = in.read(bys);
System.out.println(new String(bys,0,len));
//5.关闭资源
s.close();
fis.close();
}
}
/*
服务端.
1.建立端点ServerSocket.
2.建立文件输出流.
3.获取socket输入流中的数据,把获取到的数据写到硬盘
4.用socket输出流返回给客户端信息.
5.关闭资源.
*/
class PicServer
{
public static void main(String[] args) throws Exception
{
//1.创建端点,并接收客户端信息
ServerSocket ss = new ServerSocket(10008);
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress()+"..con");
//2.建立文件输出流
FileOutputStream fos = new FileOutputStream("b.jpg");
//3.获取socket输入流中的数据,并用文件输出流写到硬盘
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int num = 0;
while ((num=in.read(buf))!=-1)
{
fos.write(buf,0,num);
}
//4.用socket输出流给客户端返回信息
OutputStream out = s.getOutputStream();
out.write("It's done.".getBytes());
//5.关闭资源
s.close();
fos.close();
}
}
TCP协议--客户端并发上传图片--多线程
[java] view
plaincopy
import java.io.*;
import java.net.*;
//服务端
class PicServerThread implements Runnable
{
private Socket s;
PicServerThread(Socket s)
{
this.s = s;
}
public void run()
{
int count = 1;
String ip = s.getInetAddress().getHostAddress();
try
{
System.out.println(ip+"..con");
File file = new File(ip+"("+(count)+")"+".jpg");
//用循环判断文件是否存在
while (file.exists())
file = new File(ip+"("+(count++)+")"+".jpg");
//2.建立文件输出流
FileOutputStream fos = new FileOutputStream(file);
//3.获取socket输入流中的数据,并用文件输出流写到硬盘
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int num = 0;
while ((num=in.read(buf))!=-1)
{
fos.write(buf,0,num);
}
//4.用socket输出流给客户端返回信息
OutputStream out = s.getOutputStream();
out.write("It's done.".getBytes());
//5.关闭资源
s.close();
fos.close();
}
catch (Exception e)
{
throw new RuntimeException(ip+"上传失败");
}
}
}
//服务端
class ServerThreadTest
{
public static void main(String[] args) throws Exception
{
//1.创建端点,并接收客户端信息
ServerSocket ss = new ServerSocket(10008);
while (true)
{
Socket s = ss.accept();
new Thread(new PicServerThread(s)).start();
}
}
}
//客户端
class PicClientThread
{
public static void main(String[] args) throws Exception
{
//判断是否通过主函数传值进来进来
if (args.length!=1)
{
System.out.println("请选择一个jpg文件");
return ;
}
//判断文件是否存在
File file = new File(args[0]);
if (!(file.exists() && file.isFile()))
{
System.out.println("该文件有问题,要么不存在,要么不是文件");
return ;
}
//判断文件格式是否正确
if (!file.getName().endsWith(".jpg"))
{
System.out.println("图片格式错误");
return ;
}
//判断文件大小是否超过5M
if (file.length() > 1024*1024*5)
{
System.out.println("图片超过5M");
return ;
}
//1.创建端点
Socket s = new Socket("192.168.1.250",10008);
//2.获取图片数据
FileInputStream fis = new FileInputStream(file);
//3.获取socket输出流,把数据发送到服务端
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int num = 0;
while ((num=fis.read(buf))!=-1)
{
out.write(buf,0,num);
}
//为socket输出流做标记,数据已发送完,结束阻塞
s.shutdownOutput();
//4.接收服务端返回的数据
InputStream in = s.getInputStream();
byte[] bys = new byte[1024];
int len = in.read(bys);
System.out.println(new String(bys,0,len));
//5.关闭资源
s.close();
fis.close();
}
}
TCP协议--客户端并发登陆
[java] view
plaincopy
import java.io.*;
import java.net.*;
//客户端
class LoginClient
{
public static void main(String[] args) throws Exception
{
//建立端点
Socket s = new Socket("127.0.0.1",10009);
//用字符读取流读取键盘录入
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
//获取socket输出流,向服务端发送数据
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
//获取socket输入流,以获取服务端返回数据
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
//限制输入3次
for (int x=0; x<3; x++)
{
line=br.readLine();
if (line==null)
break;
pw.println(line);
String info = brin.readLine();
System.out.println(info);
if (info.contains("欢迎"))
return;
}
s.close();
br.close();
}
}
class LoginServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10009);
while (true)
{
Socket s = ss.accept();
new Thread(new UserThread(s)).start();
}
}
}
//服务端线程
class UserThread implements Runnable
{
private Socket s;
UserThread(Socket s)
{
this.s = s;
}
public void run()
{
//老师的思想
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+".....con");
try
{ //限制输入3次
for (int x=0; x<3; x++)
{
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String user = brin.readLine();
if(user==null)
break;
BufferedReader br =
new BufferedReader(new FileReader("user.txt"));
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
String line = null;
//定义一个标记
boolean flag = false;
while ((line=br.readLine())!=null)
{
if (user.equals(line))
{
flag = true;
break;
}
}
if (flag)
{
System.out.println("登陆成功");
pw.println("欢迎"+user);
break;
}
else
{
System.out.println(user+"尝试登陆");
pw.println(user+"用户名错误");
}
}
s.close();
}
catch (Exception e)
{
throw new RuntimeException(ip+"校验失败");
}
/*自己的思想
try
{
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+".....con");
PrintWriter pw = null;
for (int x=0; x<3; x++)
{
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String user = brin.readLine();
if(user==null)
break;
BufferedReader br =
new BufferedReader(new FileReader("user.txt"));
pw = new PrintWriter(s.getOutputStream(),true);
System.out.println(user+"尝试登陆");
String line = null;
while ((line=br.readLine())!=null)
{
if (user.equals(line))
{
System.out.println("登陆成功");
pw.println("欢迎"+user);
return ;
}
}
pw.println(user+"用户名错误");
System.out.println("登陆失败");
}
pw.println("您的次数用尽");
}
catch (Exception e)
{
throw new RuntimeException("校验失败");
}
*/
}
}
URL:代表一个统一资源定位符,是指向互联网资源的指针,资源可以是简单的文本或目录,也可以是更为复杂对象的引用,如对数据库或搜索引擎的查询;
常用方法:
①int getDefaultPort(): 获取与此URL关联协议的默认端口;
②String getFile(): 获取此URL的文件名;
③String getHost(): 获取此URL的主机名;
④String getPath():或取此URL的路径;
⑤int getPort(): 获取此URL的端口号;
⑥ String getProtocol(): 获取此URL的协议名称;
⑦String getQuery(): 获取此URL的查询部分;
代码
[java] view
plaincopy
import java.net.*;
class URLDemo
{
public static void main(String[] args) throws Exception
{
//URL url=new URL("http://192.168.1.13:11000/myweb/demo.html");
URL url=new URL("http://192.168.1.13:11000/myweb/demo.html?name=haha&age=30");
System.out.println("getProtocol():"+url.getProtocol()); //http
System.out.println("getHost():"+url.getHost());//192.168.1.13
System.out.println("getDefaultPort():"+url.getDefaultPort());//80,如果关联的协议没有默认的端口,则值为-1;
System.out.println("getPort():"+url.getPort()); // 11000,如果没有设置则为-1;
System.out.println("getPath():"+url.getPath());// /myweb/demo.html
System.out.println("getFile():"+url.getFile());///myweb/demo.html?name=haha&age=30
System.out.println("getQuery():"+url.getQuery());//name=haha&age=30
/* int port = url.getPort();
if(port==-1)
port =80;
getPort() = -1
*/
}
}
URLConnection:作用类似于socket,其实内部封装了socket,所以可以获取网络输入输出流,通过URL和URLConnection可以方便的对应用层网络数据进行读取和操作;
代码
[java] view
plaincopy
import java.net.*;
import java.io.*;
class URLConnectionDemo
{
public static void main(String[] args) throws Exception
{
URL url=new URL("http://192.168.1.13:8080/myweb/demo.html");
URLConnection conn = url.openConnection();
System.out.println(conn+"-------");
InputStream in = conn.getInputStream();
byte [] buf =new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
}
}
自定义图形化界面浏览器
[java] view
plaincopy
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
class MyIEByGUI
{
private Frame f;
private TextField tf;
private Button but;
private TextArea ta;
private Dialog d;
private Label lab;
private Button okBut;
MyIEByGUI()
{
init();
}
public void init()
{
f = new Frame("My IE");
f.setBounds(300,100,500,400);
f.setLayout(new FlowLayout());
tf = new TextField(40);
but = new Button("转到");
ta = new TextArea(20,50);
d = new Dialog(f,"提示信息-self",true);
d.setBounds(400,200,240,200);
d.setLayout(new FlowLayout());
lab =new Label();
okBut=new Button("确定");
d.add(lab);
d.add(okBut);
f.add(tf);
f.add(but);
f.add(ta);
myEvent();
f.setVisible(true);
}
public void myEvent()
{
but.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
showWebPage();
}
catch (Exception ex)
{
}
}
});
tf.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
{
try
{
showWebPage();
}
catch (Exception ex)
{
}
}
}
});
okBut.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
d.setVisible(false);
}
});
d.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
d.setVisible(false);
}
});
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
private void showWebPage() throws Exception
{
ta.setText("");
//http://192.168.1.13:8080/myweb/demo.html
String url =tf.getText();
int index1 = url.indexOf("//")+2;
int index2 = url.indexOf("/",index1);
String str =url.substring(index1,index2);
String[] arr = str.split(":");
String host = arr[0];
int port = Integer.parseInt(arr[1]);
String dir = url.substring(index2);
//ta.setText(url);
ta.setText(port+","+null);
//建立Socket客户端
Socket s = new Socket(host,port);
//发送请求消息头
PrintWriter out = new PrintWriter(s.getOutputStream(),true);//别忘了加true
out.println("GET "+dir+" HTTP/1.1");
out.println("Accept: */*");
out.println("Accept-Language: zh-cn");
out.println("Host: 192.168.1.13:11000");
out.println("Connection: Keep-Closed");
out.println();//记得一定要加空行
out.println();
BufferedReader bufr =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bufr.readLine())!=null)
{
ta.append(line+"\r\n");
}
s.close();
}
public static void main(String[] args)
{
new MyIEByGUI();
}
}
private void showWebPage() throws Exception
{
//使用URL和URLConnection对showWebPage改写。
//很明显,这两个封装的应用层对象使用起来更方便简洁
ta.setText("");
String urlPath =tf.getText();
URL url=new URL(urlPath);
URLConnection conn = url.openConnection();
//System.out.println(conn);
InputStream in = conn.getInputStream();
byte [] buf =new byte[1024];
int len = in.read(buf);
ta.setText(new String(buf,0,len));
}
域名解析:用IP地址登陆网站,数字不好记忆,习惯用主机名,如www.baidu.com,从主机名到获得该主机名对应的IP地址的过程,就是域名解析,它一般是DNS服务器完成的;
域名解析步骤大致分为2步:
①查找本地的IP地址和主机名映射表,如果存在映射,则使用本机映射,如:127.0.0.1和localhost的对应关系就在这个映射表中,通过对映射文件进行配置可以实现一些功能,如:将常用网站配置在表中,这样速度快些,还可以屏蔽过滤一些垃圾网站;
②如果第一步没有找到,就会去设置的DNS服务器查找,找到对应的IP地址,获取地址后,再返回给本机IP地址,本机再通过IP地址链接上想要访问的网站。
------ ASP.Net+Android+IO开发.Net培训期待与您交流! ------
总结内容来源于黑马毕老师的java基础教学视频
网络编程:
为了实现不同主机之间的数据传输和通信 。
网络模型:
OSI模型:从顶到底层 分别是: 应用层,表示层,会话层,传输层,网络层,数据链路层,物理层,分七层;
TCP/IP模型:它由应用层,传输层,网际层,网络接入组成;
FTP,HTTP都在应用层,TCP,UDP在传输层,IP在网际层。
网络通讯的三个要素:
1.IP地址:是主机在网络上的地址,在网上的唯一标识,127.0.0.1是本地回环地址,可测试网卡是否损坏;
2.端口号:数据要发送到对方指定的应用程序上,为了标识这些应用程序,用数字对其标识,这些数字就是端 口,或被称为逻辑端口;它并无物理实体与之对应;有效端口号从0~65535,其中0~1024是系统保留的 端口号;
一些常见的端口:浏览器:80 ; tomcat服务器:8080; mysql:3306;
3.传输协议:要完成传输,还要遵守相同的通信协议,国际通用协议是 TCP/IP协议,既能用于局域网,也可用于广域网,除了TCP/IP,还有 UDP,FTP,HTTP等协议;
数据封包:数据从应用层开始,每经一层,都加入该层的标识信息,直到物理层,这个过程叫数据封包,之后 变成二进制数据从物理设备上输出;
数据拆包:去掉每层的标识信息,获取数据的过程就是拆包过程;
网络编程现阶段主要是在网际层,传输层,而javaweb开发主要是在应用层;
java中对各个层都创建了对象与之对应,以方便我们开发使用;
IP地址:是数字,由四段组成,如192.168.1.1,使用时不便于记忆,所以有与之对应的主机名,主机名与IP地址相对应;IP常用的方法如下:都在java。net包中;
InetAddress: getLocalHost();可获取主机名和本地地址;
getHostAddress():主机地址的字符串表现形式;
getHostName():获取主机名称;
如果网络获取主机名称,可能出现解析不成功的情况,那么IP地址就是主机名,getByName("")可通过给定主机名,获取主机的IP地址;
代码:
[java] view
plaincopy
//IP协议类InetAddress
import java.net.*;
import java.util.*;
class InetAddressDemo
{
public static void main(String[] args) throws Exception
{
InetAddress i = InetAddress.getLocalHost();
System.out.println(i.toString());
InetAddress[] ia = InetAddress.getAllByName("www.baidu.com");
System.out.println(Arrays.asList(ia));
}
}
TCP和UDP协议:两者都在传输层;
两者的区别:
1.UDP:(User Datagram Protocol),用户数据报协议,是一种面向无连接的不可靠协议,它将数据源和目的封装成数据报包,在不需要建立连接的情况下就可实现传输,每个数据报包大小限制在64K内,特点是传输速度快;存在数据丢失的可能,主要应用于即时数据的传输,如QQ聊天程序,对话机,网络视频会议等;
2.TCP:(Transmission Control Protocol),传输控制协议,它是面向连接的可靠的传输协议,通过三次握手的形式完成数据传输通道的连接,传输大量的数据,特点是速度相对较慢,适合对数据完整性要求高的程序,如下载应用程序;
Socket:(插座,套接字):
网络编程其实就是socket编程,它是为网络服务的一种机制,每个应用程序都有一个socket通信端点,可以把socket想象为每个应用程序的插座,通信的两端都有socket,数据在两个socket之间通过IO传输;
UDP传输:UDP两端是发送端和接受端;
DatagramSocekt:UDP传输专用的程序通信断电,既能发送也能接受;
DatagramPacket: 数据报包,封装了UDP传输的数据报包,里面可以设置发送目的地的IP地址,端口和内容;
广播地址:每个网段尾数为255的IP 地址,如192.168.1.255就是一个广播地址;
UDP协议类及其使用
[java] view
plaincopy
import java.net.*;
import java.io.*;
/*
需求:通过udp传输方式,将一段文字数据发送出去
思路:
1.建立udpsochet服务.
2.提供数据,并将数据封装到数据包中.
3.通过soket服务发送功能,将数据发出去.
*/
class UdpSend
{
public static void main(String[] args) throws Exception
{
//1.创建udp服务,通过DatagramSocket对象.
DatagramSocket ds = new DatagramSocket(8888);
//2.确定数据,并封装成数据包.
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line=br.readLine())!=null)
{
byte[] buf = line.getBytes();
DatagramPacket dp =
new DatagramPacket(buf,buf.length,InetAddress.getByName(""),10000);
//3通过soket服务,将已有的数据包发送出去.通过send方法.
ds.send(dp);
if ("over".equals(line))
break;
}
//4.关闭资源
ds.close();
}
}
/*
需求:
定义一个应用程序,用于接收udp协议传输并处理.
思路:
1.定义udpsocket服务.通常会监听一个端口,其实就是给这个接收端定义数字标识
方便于明确哪些数据过来该应用程序可以处理.
2.定义一个数据包,因为要存储接收到的字节数据,
数据包对象中有更多功能可以提取字节数据中不同数据信息.
3.通过socket服务的receive方法将收到数据存入已定义好的数据包中.
4.通过数据包对象的特有功能,将这些不同数据取出.打印在控制台上.
5.关闭资源
*/
class UdpReceive
{
public static void main(String[] args) throws Exception
{
//1.创建udpsocket,建立端点
DatagramSocket ds = new DatagramSocket(10000);
//可以达到重复接收数据的目的
while(true)
{
//2.定义数据包,用于存储数据.
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,1024);
//3.通过服务的receive方法将收到的数据存入到数据包中.
ds.receive(dp);
//4.通过数据包的方法获取其中的数据.
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println(ip+"::"+data+"::"+port);
//5.关闭资源
//ds.close();
}
}
}
UDP协议编写聊天程序
[java] view
plaincopy
/*
知识点:
UDP协议, 线程, IO
编写一个聊天程序
收数据和发数据需要同时执行,那就需要用到多线程技术.
一个线程控制收,一个线程控制发.
因为收和发动作是不一致的,所以要定义两个run方法,
而且这两个方法要封装到不同类中.
*/
import java.net.*;
import java.io.*;
class Send implements Runnable
{
private DatagramSocket ds;
Send(DatagramSocket ds)
{
this.ds = ds;
}
public void run()
{
try
{
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line=br.readLine())!=null)
{
if("over".equals(line))
System.exit(0);
byte[] buf = line.getBytes();
DatagramPacket dp =
new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10005);
//将定义好的数据包发送到指定主机的指定端口
ds.send(dp);
}
}
catch (Exception e)
{
throw new RuntimeException("发送端失败");
}
}
}
class Rece implements Runnable
{
private DatagramSocket ds;
Rece(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());
System.out.println(ip+".."+data);
}
}
catch (Exception e)
{
throw new RuntimeException("发送端失败");
}
}
}
class CharTest
{
public static void main(String[] args) throws Exception
{
DatagramSocket sendSocket = new DatagramSocket();
DatagramSocket receSocket = new DatagramSocket(10005);
new Thread(new Send(sendSocket)).start();
new Thread(new Rece(receSocket)).start();
}
}
TCP传输:对应的是客户端和服务端
Socket:TCP传输客户端通信端点;
ServerSocket: TCP传输服务端端点;serversocket(port,backlog)这个构造函数中的backlog用于指定客户端的最大连接数;
因为TCP需要建立连接,所以socket客户端一建立就要指定服务端的IP和端口,而在服务端建立时,要设置监听的端口,TCP连接成功后,在客户端和服务端就会产生网络流,客户端提供对网络流进行读写的输入流和输出流对象,服务端操作网络流时,先获取客户端的socket对象,然后利用该socket的字节输入输出流进行读写操作,客户端和服务端进行多次交互时,注意阻塞式方法对程序的影响;
TCP代码演示一:
演示TCP传输。
1.tcp分客户端和服务端。
2.客户端对应的对象是Socket。
服务端对应的对象是SeverSocket
TCP协议及其使用
[java] view
plaincopy
/*
演示tcp传输.
1.tcp分客户端和服务端.
2.客户端对应的对象是Socket.
服务端对应的对象是ServerSocket.
客户端:
通过查阅socket对象,发现该对象建立时,就可以去连接主机.
因为tcp是面向连接的.所以在建立socket服务时,
就要有服务端存在.并连接成功.形成通路后,在该通道进行数据传输.
需求:给服务端发送一个文本数据.
步骤:
1.创建socket服务.并指定要连接的主机和端口.
2.获取socket中的输出流,在流中写入数据.
*/
import java.net.*;
import java.io.*;
class TcpClient
{
public static void main(String[] args) throws Exception
{
//创建客户端socket服务.指定目的主机和端口
Socket s = new Socket("LocalHost",10001);
//为了发送数据,应该获取socket中的输出流.
OutputStream out = s.getOutputStream();
out.write("tcp is coming".getBytes());
s.close();
}
}
/*
需求:定义端点接收数据并打印在控制台上.
服务端:
1.建立服务端的socket服务.ServerSocket();并监听一个端口
2.获取连接过来的客户端对象.通过 ServerSocket的accept方法,这个方法是阻塞的.
3.客户端如果发过来数据,那么服务端要使用对应的客户端对象,
并获取到该客户端对象的读取流来读取发过来的数据.
4.关闭服务端.(可选)
*/
class TcpServer
{
public static void main(String[] args) throws Exception
{
//建立服务端socket服务.并监听一个端口
ServerSocket ss = new ServerSocket(10001);
//通过accept方法获取连接过来的客户端对象
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"....connected");
//获取客户端发送过来的数据,使用客户端对象的读取流
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
s.close();
ss.close();
}
}
TCP协议的客户端和服务端互访
[java] view
plaincopy
/*
演示tcp传输的客户端和服务端的互访.
需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息.
*/
/*
客户端:
1.建立socket服务,指定要连接的主机和端口
2.获取输出流,将数据写入,通过网络发送给服务端.
3.获取输入流,将服务端反馈的数据获取到并打印
4.关闭客户端资源.
*/
import java.io.*;
import java.net.*;
class TcpClient2
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("LocalHost",10002);
OutputStream out = s.getOutputStream();
out.write("hello server".getBytes());
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
}
}
class TcpServer2
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10002);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+".....connected");
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
OutputStream out = s.getOutputStream();
out.write("received,hello client".getBytes());
}
}
TCP协议练习
[java] view
plaincopy
/*
需求:建立一个文本转换服务器.
客户端给服务端发送文本,服务端会将文本转成大写在返回客户端.
而且客户端可以不断的进行文本转换.当客户端输入over时,转换结束.
分析:
客户端:
既然是操作设备上的数据,那么可以使用io技术,并按照io操作规律思考.
源,键盘录入.
目的:网络设备,网络输出流.
而且操作的是文本数据.可以选择字符流.
步骤
1.建立服务.
2.获取键盘录入.
3.将数据发给服务端.
4.获取服务端返回的大写数据.
5.关闭资源.
都是文本数据,可以使用字符流进行操作,同时提高效率,加入缓冲.
*/
import java.io.*;
import java.net.*;
class TransClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("localhost",10010);
//定义键盘录入的字符流
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
//获取socket的输出流并转成字符输出流,发给服务端
OutputStreamWriter osw = new OutputStreamWriter(s.getOutputStream());
BufferedWriter bwout = new BufferedWriter(osw);
//定义一个socket读取流,读取服务端返回的大写信息.
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while ((line=br.readLine())!=null)
{
if(line.equals("over"))
break;
bwout.write(line);
bwout.newLine();
bwout.flush();
//服务端返回的数据
String str = brin.readLine();
System.out.println("server......"+str.toUpperCase());
}
s.close();
br.close();
}
}
/*
服务端:
源:socket读取流
目的:socket输出流
都是字符,用字符流
*/
class TransServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10010);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"........connected");
//读取socket读取流中的数据
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
//获取socket输出流,将大写数据写道输出流中,发给客户端
BufferedWriter bwout =
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while ((line=brin.readLine())!=null)
{
System.out.println(line);
if(line.equals("over"))
break;
bwout.write(line);
bwout.newLine();
bwout.flush();
}
s.close();
}
}
/*
该例子出现的问题.
现象:客服端和服务端都在莫名的等待.
为什么呢?
因为客户端和服务端都有阻塞式方法,这些方法没读到结束标记,
那么就导致两端都在等待.
*/
TCP协议--上传TXT文件
[java] view
plaincopy
//需求:用Tcp协议复制txt文件,从客户端上传到服务端
/*
客户端:
分析.
操作硬盘上的文件用到io流,
源:硬盘
目的:网络输出流
操作的文本文件,可以用字符流
步骤.
1.建立一个socket服务
2.获取txt文件内容
3.将数据发给服务端
4.接收服务端返回的信息
5.关闭资源
*/
import java.io.*;
import java.net.*;
class TextClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("192.168.1.250",10100);
//定义一个读取字符流缓冲区
BufferedReader br = new BufferedReader(new FileReader("tcp.txt"));
//获取socket输出流,把读取流中的数据写到socket输出流
BufferedWriter bwout =
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//获取socket输入流,接收服务端返回的数据
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while ((line=br.readLine())!=null)
{
bwout.write(line);
bwout.newLine();
bwout.flush();
}
s.shutdownOutput();
String str = brin.readLine();
System.out.println(str);
s.close();
br.close();
}
}
/*
服务端:
分析.
接收socket输入流数据,
源:网络输入流
目的:硬盘
操作的文本文件,可以用字符流
步骤.
1.建立一个socket服务
2.获取socket输入流中的数据
3.将数据用文件输出流写道txt文件中
4.给客户端发送已成功信息
5.关闭资源
*/
class TextServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10100);
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress()+"...connected");
//获取socket输入流,接收客户端发来的数据
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
//定义一个文件输出流缓冲区
BufferedWriter bw = new BufferedWriter(new FileWriter("tcp-2.txt"));
//获取socket输出流,把数据通过socket输出流返回给客户端
BufferedWriter bwout =
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while ((line=brin.readLine())!=null)
{
bw.write(line);
bw.newLine();
bw.flush();
}
bwout.write("文件上传成功");
bwout.close();
s.close();
bw.close();
}
}
TCP协议--上传图片文件
[java] view
plaincopy
//需求:客户端上传图片到服务端
/*
客户端.
1.创建端点socket.
2.用文件输入流获取图片文件数据.
3.用socket输出流将数据上传给服务端.
4.接收服务端返回的socket输入流.
5.关闭资源.
*/
import java.io.*;
import java.net.*;
class PicClient
{
public static void main(String[] args) throws Exception
{
//1.创建端点
Socket s = new Socket("192.168.1.250",10008);
//2.获取图片数据
FileInputStream fis = new FileInputStream("a.jpg");
//3.获取socket输出流,把数据发送到服务端
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int num = 0;
while ((num=fis.read(buf))!=-1)
{
out.write(buf,0,num);
}
//为socket输出流做标记,数据已发送完,结束阻塞
s.shutdownOutput();
//4.接收服务端返回的数据
InputStream in = s.getInputStream();
byte[] bys = new byte[1024];
int len = in.read(bys);
System.out.println(new String(bys,0,len));
//5.关闭资源
s.close();
fis.close();
}
}
/*
服务端.
1.建立端点ServerSocket.
2.建立文件输出流.
3.获取socket输入流中的数据,把获取到的数据写到硬盘
4.用socket输出流返回给客户端信息.
5.关闭资源.
*/
class PicServer
{
public static void main(String[] args) throws Exception
{
//1.创建端点,并接收客户端信息
ServerSocket ss = new ServerSocket(10008);
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress()+"..con");
//2.建立文件输出流
FileOutputStream fos = new FileOutputStream("b.jpg");
//3.获取socket输入流中的数据,并用文件输出流写到硬盘
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int num = 0;
while ((num=in.read(buf))!=-1)
{
fos.write(buf,0,num);
}
//4.用socket输出流给客户端返回信息
OutputStream out = s.getOutputStream();
out.write("It's done.".getBytes());
//5.关闭资源
s.close();
fos.close();
}
}
TCP协议--客户端并发上传图片--多线程
[java] view
plaincopy
import java.io.*;
import java.net.*;
//服务端
class PicServerThread implements Runnable
{
private Socket s;
PicServerThread(Socket s)
{
this.s = s;
}
public void run()
{
int count = 1;
String ip = s.getInetAddress().getHostAddress();
try
{
System.out.println(ip+"..con");
File file = new File(ip+"("+(count)+")"+".jpg");
//用循环判断文件是否存在
while (file.exists())
file = new File(ip+"("+(count++)+")"+".jpg");
//2.建立文件输出流
FileOutputStream fos = new FileOutputStream(file);
//3.获取socket输入流中的数据,并用文件输出流写到硬盘
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int num = 0;
while ((num=in.read(buf))!=-1)
{
fos.write(buf,0,num);
}
//4.用socket输出流给客户端返回信息
OutputStream out = s.getOutputStream();
out.write("It's done.".getBytes());
//5.关闭资源
s.close();
fos.close();
}
catch (Exception e)
{
throw new RuntimeException(ip+"上传失败");
}
}
}
//服务端
class ServerThreadTest
{
public static void main(String[] args) throws Exception
{
//1.创建端点,并接收客户端信息
ServerSocket ss = new ServerSocket(10008);
while (true)
{
Socket s = ss.accept();
new Thread(new PicServerThread(s)).start();
}
}
}
//客户端
class PicClientThread
{
public static void main(String[] args) throws Exception
{
//判断是否通过主函数传值进来进来
if (args.length!=1)
{
System.out.println("请选择一个jpg文件");
return ;
}
//判断文件是否存在
File file = new File(args[0]);
if (!(file.exists() && file.isFile()))
{
System.out.println("该文件有问题,要么不存在,要么不是文件");
return ;
}
//判断文件格式是否正确
if (!file.getName().endsWith(".jpg"))
{
System.out.println("图片格式错误");
return ;
}
//判断文件大小是否超过5M
if (file.length() > 1024*1024*5)
{
System.out.println("图片超过5M");
return ;
}
//1.创建端点
Socket s = new Socket("192.168.1.250",10008);
//2.获取图片数据
FileInputStream fis = new FileInputStream(file);
//3.获取socket输出流,把数据发送到服务端
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int num = 0;
while ((num=fis.read(buf))!=-1)
{
out.write(buf,0,num);
}
//为socket输出流做标记,数据已发送完,结束阻塞
s.shutdownOutput();
//4.接收服务端返回的数据
InputStream in = s.getInputStream();
byte[] bys = new byte[1024];
int len = in.read(bys);
System.out.println(new String(bys,0,len));
//5.关闭资源
s.close();
fis.close();
}
}
TCP协议--客户端并发登陆
[java] view
plaincopy
import java.io.*;
import java.net.*;
//客户端
class LoginClient
{
public static void main(String[] args) throws Exception
{
//建立端点
Socket s = new Socket("127.0.0.1",10009);
//用字符读取流读取键盘录入
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
//获取socket输出流,向服务端发送数据
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
//获取socket输入流,以获取服务端返回数据
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
//限制输入3次
for (int x=0; x<3; x++)
{
line=br.readLine();
if (line==null)
break;
pw.println(line);
String info = brin.readLine();
System.out.println(info);
if (info.contains("欢迎"))
return;
}
s.close();
br.close();
}
}
class LoginServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10009);
while (true)
{
Socket s = ss.accept();
new Thread(new UserThread(s)).start();
}
}
}
//服务端线程
class UserThread implements Runnable
{
private Socket s;
UserThread(Socket s)
{
this.s = s;
}
public void run()
{
//老师的思想
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+".....con");
try
{ //限制输入3次
for (int x=0; x<3; x++)
{
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String user = brin.readLine();
if(user==null)
break;
BufferedReader br =
new BufferedReader(new FileReader("user.txt"));
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
String line = null;
//定义一个标记
boolean flag = false;
while ((line=br.readLine())!=null)
{
if (user.equals(line))
{
flag = true;
break;
}
}
if (flag)
{
System.out.println("登陆成功");
pw.println("欢迎"+user);
break;
}
else
{
System.out.println(user+"尝试登陆");
pw.println(user+"用户名错误");
}
}
s.close();
}
catch (Exception e)
{
throw new RuntimeException(ip+"校验失败");
}
/*自己的思想
try
{
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+".....con");
PrintWriter pw = null;
for (int x=0; x<3; x++)
{
BufferedReader brin =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String user = brin.readLine();
if(user==null)
break;
BufferedReader br =
new BufferedReader(new FileReader("user.txt"));
pw = new PrintWriter(s.getOutputStream(),true);
System.out.println(user+"尝试登陆");
String line = null;
while ((line=br.readLine())!=null)
{
if (user.equals(line))
{
System.out.println("登陆成功");
pw.println("欢迎"+user);
return ;
}
}
pw.println(user+"用户名错误");
System.out.println("登陆失败");
}
pw.println("您的次数用尽");
}
catch (Exception e)
{
throw new RuntimeException("校验失败");
}
*/
}
}
URL:代表一个统一资源定位符,是指向互联网资源的指针,资源可以是简单的文本或目录,也可以是更为复杂对象的引用,如对数据库或搜索引擎的查询;
常用方法:
①int getDefaultPort(): 获取与此URL关联协议的默认端口;
②String getFile(): 获取此URL的文件名;
③String getHost(): 获取此URL的主机名;
④String getPath():或取此URL的路径;
⑤int getPort(): 获取此URL的端口号;
⑥ String getProtocol(): 获取此URL的协议名称;
⑦String getQuery(): 获取此URL的查询部分;
代码
[java] view
plaincopy
import java.net.*;
class URLDemo
{
public static void main(String[] args) throws Exception
{
//URL url=new URL("http://192.168.1.13:11000/myweb/demo.html");
URL url=new URL("http://192.168.1.13:11000/myweb/demo.html?name=haha&age=30");
System.out.println("getProtocol():"+url.getProtocol()); //http
System.out.println("getHost():"+url.getHost());//192.168.1.13
System.out.println("getDefaultPort():"+url.getDefaultPort());//80,如果关联的协议没有默认的端口,则值为-1;
System.out.println("getPort():"+url.getPort()); // 11000,如果没有设置则为-1;
System.out.println("getPath():"+url.getPath());// /myweb/demo.html
System.out.println("getFile():"+url.getFile());///myweb/demo.html?name=haha&age=30
System.out.println("getQuery():"+url.getQuery());//name=haha&age=30
/* int port = url.getPort();
if(port==-1)
port =80;
getPort() = -1
*/
}
}
URLConnection:作用类似于socket,其实内部封装了socket,所以可以获取网络输入输出流,通过URL和URLConnection可以方便的对应用层网络数据进行读取和操作;
代码
[java] view
plaincopy
import java.net.*;
import java.io.*;
class URLConnectionDemo
{
public static void main(String[] args) throws Exception
{
URL url=new URL("http://192.168.1.13:8080/myweb/demo.html");
URLConnection conn = url.openConnection();
System.out.println(conn+"-------");
InputStream in = conn.getInputStream();
byte [] buf =new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
}
}
自定义图形化界面浏览器
[java] view
plaincopy
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
class MyIEByGUI
{
private Frame f;
private TextField tf;
private Button but;
private TextArea ta;
private Dialog d;
private Label lab;
private Button okBut;
MyIEByGUI()
{
init();
}
public void init()
{
f = new Frame("My IE");
f.setBounds(300,100,500,400);
f.setLayout(new FlowLayout());
tf = new TextField(40);
but = new Button("转到");
ta = new TextArea(20,50);
d = new Dialog(f,"提示信息-self",true);
d.setBounds(400,200,240,200);
d.setLayout(new FlowLayout());
lab =new Label();
okBut=new Button("确定");
d.add(lab);
d.add(okBut);
f.add(tf);
f.add(but);
f.add(ta);
myEvent();
f.setVisible(true);
}
public void myEvent()
{
but.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
showWebPage();
}
catch (Exception ex)
{
}
}
});
tf.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
{
try
{
showWebPage();
}
catch (Exception ex)
{
}
}
}
});
okBut.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
d.setVisible(false);
}
});
d.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
d.setVisible(false);
}
});
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
private void showWebPage() throws Exception
{
ta.setText("");
//http://192.168.1.13:8080/myweb/demo.html
String url =tf.getText();
int index1 = url.indexOf("//")+2;
int index2 = url.indexOf("/",index1);
String str =url.substring(index1,index2);
String[] arr = str.split(":");
String host = arr[0];
int port = Integer.parseInt(arr[1]);
String dir = url.substring(index2);
//ta.setText(url);
ta.setText(port+","+null);
//建立Socket客户端
Socket s = new Socket(host,port);
//发送请求消息头
PrintWriter out = new PrintWriter(s.getOutputStream(),true);//别忘了加true
out.println("GET "+dir+" HTTP/1.1");
out.println("Accept: */*");
out.println("Accept-Language: zh-cn");
out.println("Host: 192.168.1.13:11000");
out.println("Connection: Keep-Closed");
out.println();//记得一定要加空行
out.println();
BufferedReader bufr =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bufr.readLine())!=null)
{
ta.append(line+"\r\n");
}
s.close();
}
public static void main(String[] args)
{
new MyIEByGUI();
}
}
private void showWebPage() throws Exception
{
//使用URL和URLConnection对showWebPage改写。
//很明显,这两个封装的应用层对象使用起来更方便简洁
ta.setText("");
String urlPath =tf.getText();
URL url=new URL(urlPath);
URLConnection conn = url.openConnection();
//System.out.println(conn);
InputStream in = conn.getInputStream();
byte [] buf =new byte[1024];
int len = in.read(buf);
ta.setText(new String(buf,0,len));
}
域名解析:用IP地址登陆网站,数字不好记忆,习惯用主机名,如www.baidu.com,从主机名到获得该主机名对应的IP地址的过程,就是域名解析,它一般是DNS服务器完成的;
域名解析步骤大致分为2步:
①查找本地的IP地址和主机名映射表,如果存在映射,则使用本机映射,如:127.0.0.1和localhost的对应关系就在这个映射表中,通过对映射文件进行配置可以实现一些功能,如:将常用网站配置在表中,这样速度快些,还可以屏蔽过滤一些垃圾网站;
②如果第一步没有找到,就会去设置的DNS服务器查找,找到对应的IP地址,获取地址后,再返回给本机IP地址,本机再通过IP地址链接上想要访问的网站。
------ ASP.Net+Android+IO开发.Net培训期待与您交流! ------
相关文章推荐
- 黑马程序员java自学总结之--网络编程
- 黑马程序员_08Java网络编程知识总结
- 黑马程序员-java网络编程入门总结
- 黑马程序员_java网络编程总结
- 黑马程序员_Java基础:网络编程总结
- java 自学日志 【十六】---网络编程
- 黑马程序员java基础篇----网络编程总结
- 黑马程序员——Java学习总结:多线程和网络编程
- 黑马程序员 Java基础知识总结-网络编程
- 黑马程序员---java网络编程学习总结
- 黑马程序员-Java网络编程学习总结
- 黑马程序员_Java基础:网络编程总结
- 黑马程序员 知识点总结-Java网络编程
- 黑马程序员-自己总结的java学习笔记(8)网络编程
- 黑马程序员_java网络编程总结
- 黑马程序员+对Java中网络编程的总结
- 黑马程序员-java网络编程总结
- 黑马程序员:Java基础总结----网络编程
- 黑马程序员--Java基础总结---网络编程