------- android培训、java培训、期待与您交流! ----------
until23
网络编程
1.概述
2.网络模型
3.IP地址
4.TCP和UDP
5.Socket
6.udp-发送端
7.udp-接收端
8.UDP-键盘录入方式数据
9.UDP-聊天
10.TCP-传输
11.TCP练习
12.TCP复制文件
概述
网络通信要素:IP地址,端口号(应用程序标识【逻辑接口】),传输协议:
(TCP(国际协议)通用协议!)
还有UDP
IP:127.0.0.1 本地回环地址!可用于测网(ping-)
IP:192.168.x.x 常用保留地址段
端口方面:0-1024 是被系统程序保留的!
(80800,80浏览网页服务的端口;3360数据库使用)
网络模型
程序员一般操作的层:
网际层是封装IP地址的层
传输层是TCP进行传输的层
(应用层用于http协议!)
IP地址
cn 如果是这个后缀的,就表示这个网址是中国的,cn是china的缩写。
com 是company的缩写,代表商业组织。
gov 是goverment的缩写,代表政府部门。
net 是network的缩写,代表主要网络支持中心,提供网络服务业务。
int 是international的缩写,代表国际组织。
edu 是education的缩写,代表教育部门。
mil 是military的缩写,代表军事部门。
org 是organization的缩写,代表社会组织,多为非赢利性的
import java.net.*;
public class IPDemo {
public static void main(String[] args) throws Exception {
InetAddress id = InetAddress.getLocalHost();//获取当前主机名称和IP地址
System.out.println(id);
//获取指定主机
InetAddress[] myid = InetAddress.getAllByName("www.baidu.com");
System.out.println(myid[0].getHostName());
System.out.println(myid[1].getHostAddress());
System.out.println(myid.length);
//115.239.210.26 百度在中国只有两台主机?
}
}
TCP和UDP
UDP |
将数据:源和目的封装成数据包,不需要建立链接 |
每个数据包的大小限制在64k里 |
因为无序连接,是不可靠协议 |
但是因为不需要连接,所以速度块 |
UTCP |
建立连接,形成传输数据通道 |
在链接中进行大数据传输 |
通过三次握手完成连接,是可靠协议 |
因为要建立连接,效率比UDP低 |
Socket
Socket是为网络服务提供的一种机制
通信的两端都有Socket
网络通信其实就是Socket间的通信
数据在两个Socket间通过IO传输
应用程序间的通信可以理解为Socket通信
udp-发送端
DatagramSocket(建立UDP服务)
DatagramPacket(byte[] buf,int length,InetAddress address/getByName,int port)将数据封装成包
过程:
建立发送端和接收端,建立数据包,电泳Socket的发送接收方法,关闭Socket.
Send(DatagramPacket p)发送 packet 数据包
receive(DatagramPacjet p )接受(阻塞方法) packet 包
udp-接收端
package until_23;
import java.io.IOException;
import java.net.*;
public class Practice {
public static void main(String[] args) throws IOException {
sendData();
receiveData();
}
public static void sendData()throws IOException
{
// 建立udp服务
DatagramSocket ds = new DatagramSocket();
//建立数据包
byte[] buf = "where are you".getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.105"),10101);
//发送
ds.send(dp);
//关闭资源
ds.close();
}
public static void receiveData()throws IOException
{
//建立服务
DatagramSocket ds = new DatagramSocket(10101);
//建立接受包
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//接受
ds.receive(dp);
//显示数据
String ip = dp.getAddress().getHostName();
String data = new String(dp.getData(),0,dp.getLength());
System.out.println(ip+data);
ds.close();
}
}
注意net.BindException异常!端口重复了!
UDP-键盘录入方式数据
public static void keySendData()throws IOException
{
DatagramSocket ds = new DatagramSocket();
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line=br.readLine())!=null)
{
if("886".equals(line))
break;
byte[] buf = line.getBytes();
DatagramPacket dp =
new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),10101);
ds.send(dp);
}
ds.close();
}
UDP-聊天
利用线程来写就成了!和上面的录入方式相差不大
TCP-传输
Sockey在建立的时候就要链接服务器(InetAddress i ,Port p)
步骤:
创建Socket服务并且指定地址和端口
拿到输入或者输出流 getOutputStream getInputStream
服务器端口:
服务端不带流,当客户端进入服务端的时候,服务器端拿了客户端的流对象,保证了客户端的唯一性!
步骤:
建立服务端:ServerSocket(绑定端口)
获取客户端对象 使用accept方法!返回的是socket类型 阻塞方法
客户端如果发过来数据!服务端是该客户端的流来获取数据
关闭服务端(正常不关!)
TCP练习
import java.io.IOException;
import java.net.*;
import java.io.*;
class Socketclass
{
public static void main(String[] args)throws Exception
{
//创建服务端
Socket s = new Socket("192.168.1.105",10101);
//上面代码成功运行证明同路已经联通了
//调用客户端的流方法
OutputStream out = s.getOutputStream();
out.write("how are you?".getBytes());
out.close();
}
}
class ServerSocketclass {
public static void main(String[] args)throws Exception
{
ServerSocket ss = new ServerSocket(10101);
Socket s = ss.accept();
String s1 = s.getInetAddress().getHostName();
System.out.println(s1);
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
in.close();
}
}
TCP复制文件
import java.net.*;
import java.io.*;
class Socket_2
{
public static void main(String[] args) throws Exception
{
//建立客户端
Socket s = new Socket("192.168.1.105",10101);
//建立流(分别是对应的键盘流和写出流)
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
/*
BufferedWriter bw =
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
*/
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
//建立读取服务端信息的流
BufferedReader bri =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=br.readLine())!=null)
{
if("over".equals(line))
break;
pw.println(line);
/*
bw.write(line.toUppercase());
bw.newLine();//因为读取的方式是"\r\n"
bw.flush();
*/
String value = bri.readLine();
System.out.println("return:"+value);
}
s.close();
}
}
class ServerSocket_2
{
public static void main(String[] args) throws Exception
{
//建立服务端
ServerSocket ss = new ServerSocket(10101);
Socket s = ss.accept();
//流
/*
BufferedWriter bw =
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
*/
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
BufferedReader bri =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bri.readLine())!=null)
{
System.out.println(line);
pw.println(line.toUpperCase());
/*
bw.write(line.toUppercase());
bw.newLine();
bw.flush();
*/
}
s.close();
ss.close();
}
}
import java.net.*;
import java.io.*;
//复制文件
class Socket_3
{
public static void main(String[] args) throws Exception
{
//建立客户端
Socket s = new Socket("192.168.1.105",10101);
//建立流(分别是对应的键盘流和写出流)
/*
BufferedWriter bw =
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
*/
BufferedReader br =
new BufferedReader(new FileReader("C:\\JW\\Day23\\TcpDemoPractice.java"));
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
//建立读取服务端信息的流
BufferedReader bri =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=br.readLine())!=null)
{
pw.println(line);
}
s.shutdownOutput();//关闭客户端的输出流,相当于给流中加入了一个结束标记-1
System.out.println(bri.readLine());
br.close();
s.close();
}
}
class ServerSocket_3
{
public static void main(String[] args) throws Exception
{
//建立服务端
ServerSocket ss = new ServerSocket(10101);
Socket s = ss.accept();
String str = s.getInetAddress().getHostAddress();
System.out.println("ip:"+str);
//流
DataInputStream dis = new DataInputStream(s.getInputStream());
long time = dis.readLong();
/*
BufferedWriter bw =
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
*/
PrintWriter pw = new PrintWriter(new FileWriter("kaka.java"),true);
BufferedReader bri =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bri.readLine())!=null)
{
pw.println(line);
}
PrintWriter pw_1 = new PrintWriter(s.getOutputStream(),true);
pw_1.println("上传成功");
s.close();
ss.close();
}
}
until24
网络编程
1.tcp上传图片
2.tcp客户端上传图片
3.tcp客户端并发登录
4.浏览器客户端-自定义服务端
5.Tomcat服务端
6.自定义浏览器(Tomcat)
7.自定义图形界面浏览器(Tomcat)
8.URL-URLConnection
9.小知识点
10.域名解析
网络编程
tcp上传图片和户端上传图片
客户端分析:
建立服务端点
读取客户端已有的图片数据
通过Socket传输给服务端
读取服务端的反馈信息
Shutdow!!!!
服务端分析:
如果不是用多线程,服务端会有局限性!
解决方法是将每一个客户端封装到独立的线程中去
就是服务端走多线程!
import java.net.*;
import java.io.*;
class TcpS_1
{
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;
}
if(file.length()>1024*1024*5)
{
System.out.println("文件大于5M,请重新选择吧!");
return;
}
Socket s = new Socket("127.0.01",10101);
FileInputStream fis =
new FileInputStream("1.jpg");
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int lin = 0;
while((lin=fis.read(buf))!=-1)
{
out.write(buf,0,lin);
}
//给客户端一个结束信息
s.shutdownOutput();
InputStream in = s.getInputStream();
byte[] bufIn = new byte[1024];
int lini = in.read(bufIn);
String str = new String(bufIn,0,lini);
System.out.println(str);
fis.close();
s.close();
}
}
class TcpR_1
{
public static void main(String[] args)throws Exception
{
ServerSocket ss = new ServerSocket(10101);
while(true)
{
Socket s = ss.accept();
new Thread(new TcpRR_1(s)).start();
}
}
}
class TcpRR_1 implements Runnable
{
private Socket s;
TcpRR_1(Socket s)
{
this.s = s;
}
public void run()
{
int count = 0;
String ip = s.getInetAddress().getHostAddress();
try{
System.out.println("ip:"+ip);
InputStream is = s.getInputStream();
File file = new File(count+".jpg");
while(file.exists())
file = new File((count++)+".jpg");
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int lin = 0;
while((lin = is.read(buf))!=-1)
{
fos.write(buf,0,lin);
}
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
pw.println("上传成功");
fos.close();
s.close();
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
}
tcp客户端并发登录
import java.net.*;
import java.io.*;
class SocketDemo
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("1024.0.0.1",10101);
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
BufferedReader brIn =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
for(int x = 0;x<3;x++)
{
line = br.readLine();
if(line==null)
break;
pw.println(line);
String ss = brIn.readLine();
System.out.println("info:"+ss);
if(ss.contains("欢迎"))
break;
}
br.close();
s.close();
}
}
class ServerSocketDemo
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10101);
while(true)
{
Socket s = ss.accept();
new Thread(new ServerThread(s)).start();
}
}
}
class ServerThread implements Runnable
{
private Socket s;
ServerThread(Socket s)
{
this.s = s;
}
public void run()
{
String str = s.getInetAddress().getHostAddress();
System.out.println("ip:::"+str);
try
{
for(int x = 3;x<0;x--)
{
BufferedReader brIn =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String name = brIn.readLine();
System.out.println("info"+name);
BufferedReader br =
new BufferedReader(new FileReader("1.txt"));
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
String line = null;
boolean flag = false;
while((line = br.readLine())!=null)
{
if(line.equals(name))
{
flag = true;
break;
}
}
if(flag)
{
System.out.println("登录成功");
pw.println("欢迎登录");
break;
}
else
{
System.out.println("登录失败,还可以尝试"+x+"次");
pw.println("登录失败");
}
br.close()
}
s.close();
}
catch (Exception e)
{
throw new RuntimeException("客户出错了");
}
}
}
Tomcat服务端
自定义浏览器(Tomcat)
ip::127.0.0.1
GET / HTTP/1.1(版本)
Accept: text/html, application/xhtml+xml, */*(能接受类型)
Accept-Language: zh-CN(语言)
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)(用户信息)
Accept-Encoding: gzip, deflate(支持的压缩形式)
Host: 127.0.0.1:11101(访问的主机)
DNT: 1
Connection: Keep-Alive(连接!保持存活)
上面是HTTP请求协议!
get请求方式!~
根据上面的代码自定义一次服务器!
看看是否会像浏览器一样返回数据!
package until_24;
import java.net.*;
import java.io.*;
public class MyIE {
public static void main(String[] args) throws Exception{
Socket s = new Socket("127.0.0.1",8080);
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
pw.println("GET /manager/demo.html HTTP/1.1");
pw.println("Accept:*/*");
pw.println("Accept-Language:zh-cn");
pw.println("Host:127.0.0.1:8080");
pw.println("Connetion:closed");
pw.println();
pw.println();
BufferedReader br =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=br.readLine())!=null)
{
System.out.println(line);
}
s.close();
}
}
200是响应消息头!反问成功
自定义图形界面浏览器(Tomcat)
package until_24;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class FramNet {
private Frame f;
private TextField tf;
private Button but;
private TextArea ta;
private Dialog df;
private Label lb;
private Button okBut;
FramNet()
{
init();
}
public void init()
{
f = new Frame("MyFrame");
f.setBounds(100,200,500,500);
f.setLayout(new FlowLayout());
df = new Dialog(f,"提示信息",true);
df.setLayout(new FlowLayout());
df.setBounds(300,500,160,100);
tf = new TextField(50);
but = new Button("Enter");
ta = new TextArea();
lb = new Label();
okBut = new Button("确定");
df.add(lb);
df.add(okBut);
f.add(tf);
f.add(but);
f.add(ta);
myEvent();
f.setVisible(true);
}
public void myEvent()
{
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
but.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
try {
showDir();
} catch (Exception e2) {
System.out.println(e2.toString());
}
}
});
tf.addKeyListener(new KeyAdapter(){
public void ketPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
{
try {
showDir();
} catch (Exception e2) {
System.out.println(e2.toString());
}
}
}
});
okBut.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
df.setVisible(false);
}
});
df.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
df.setVisible(false);
}
});
}
public void showDir() throws UnknownHostException, IOException
{
ta.setText("");
String url = tf.getText();//http://127.0.0.1:8080/manager/demo.html
int ind1 = url.indexOf("//")+2;
int ind2 = url.indexOf("/",ind1);
String ip = url.substring(ind1,ind2);
String[] str = ip.split(":");
String host = str[0];
int port = Integer.parseInt(str[1]);
String path = url.substring(ind2);
//ta.append(ip+":::"+path);
Socket s = new Socket(host,port);
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
pw.println("GET "+path+" HTTP/1.1");
pw.println("Accept:*/*");
pw.println("Accept-Language:zh-cn");
pw.println("Host:127.0.0.1:8080");
pw.println("Connetion:closed");
pw.println();
pw.println();
BufferedReader br =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=br.readLine())!=null)
{
ta.append(line+"\r\n");
}
s.close();
/*
String dirPath = ta.getText();
File file = new File(dirPath);
if(file.exists() && file.isDirectory())//判断路径
{
ta.setText("");
String[] names = file.list();
for(String name : names)
{
ta.append(name+"\r\n");
}
}
else
{
String info = "输入的信息:"+dirPath+"是错误的";
lb.setText(info);
df.setVisible(true);
}
*/
}
public static void main(String[] args) {
new FramNet();
}
}
URL-URLConnection
把地址设定为对象进行查找!~
URI类的范围要比URL的广!类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。
String getFile()
获取此 URL 的文件名。
String getHost()
获取此 URL 的主机名(如果适用)。
String getPath()
获取此 URL 的路径部分。
int getPort()
获取此 URL 的端口号。
String getProtocol()
获取此 URL 的协议名称。
String getQuery()
获取此 URL 的查询部分。
调用openConnetion 方法进行链接
小知识点
InetSocketAddress = ip+端口
域名解析
先走本地文件再走DNS