1.网络模型:

OSI参考模型、TCP/IP参考模型

数据传输的过程:向下走:封包    向上走:拆包

向上走一直拆包,直到得到数据。

2.网络通讯要素

ip地址、端口号、传输协议

Ip和端口用来找对方,确认对方身份。协议保证双方都能听懂双方的对话,常见的传输协议是:TCP、UDP

更多网络信息参考网络相关书籍和教程。

3.常用类InetAddress,此类表示互联网协议 (IP) 地址

得到InetAddress对象的几种方法:得到本地Host;通过ip;通过域名

public static void main(String[] args) throws Exception {//1.通过InetAddress.getLocalHost()得到本机InetAddress对象   /*InetAddress host = InetAddress.getLocalHost();//主机名+ipSystem.out.println(host);//Lenovo-PC/192.168.159.10   主机名+ipSystem.out.println(host.getHostAddress());//ipSystem.out.println(host.getHostName());// 主机名*///2.通过InetAddress的静态方法,传入ip得到InetAddress对象       /*InetAddress host = InetAddress.getByName("192.168.159.1");System.out.println(host.getHostAddress());//ipSystem.out.println(host.getHostName());//主机名*///3.通过域名得到InetAddress对象数组InetAddress[] is = InetAddress.getAllByName("www.baidu.com");System.out.println(is.length);//2System.out.println(is[0].getHostName());//www.baidu.com 得到域名System.out.println(is[1].getHostName());}

TCP、UDP、Socket

1.TCP与UDP的区别

(1)TCP

建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必需建立连接,所以效率低。

(2)UDP

将数据,源和目的封装成包,不需要建立连接;每个数据报的大小限制在64K内;因为不需要建立连接,所以是不可靠的传输;不需要建立连接,所以速度快。

2.Socket

Socket是为网络服务提供的一种机制;通信两段都有Socket,网络通信实际上就是Socket通信;数据在Socket间的通信是通过IO实现的。

3.UDP传输

(1)UDP收发数据使用的是DatagramSocket。数据需要封装成包DatagramPacket,需要建立发送端和接收端,这两个端是相互独立的程序。

(2)InetAddress/SocketAddress区别

InetAddress指的是IP,SocketAddress是封装了ip和端口的抽象类

(3)网络编程使用的包是java.net。一般net需要和io包一起使用。

(4)建立服务连接的DatagramSocket的创建不放在while中,会发生绑定异常.建立Socket相当于建立连接,连接只需要建立一次,如果没有断开又建立连接也会发生异常,所以建立连接Socket的创建是唯一的。

(5)因为UDP传输的两端是相互独立的程序,所以要建立两个main,启动的时候先启动接收端,再启动发送端。

(6)发送端Socket可以关闭,一般接收端Socket不用关闭

键盘发送数据的例子:

发送端要指明接收端的ip,端口。发送端的端口是随机分配的,也可以自己指定.接收端要指明接收的端口号,接收端除了可以获得数据,还可以得到发送端的ip,端口。

自己指定发送端端口号:

DatagramSocket ds = new DatagramSocket(8888);
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
(**)发送端是键盘输入,所以不用while(true)
//发送端
public class SendClass {public static void main(String[] args) throws Exception {DatagramSocket ds = new DatagramSocket();BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String line = null;while((line = br.readLine())!= null){//readLine是一个阻塞式的方法if("over".equals(line)){break;}byte[] b = line.getBytes();DatagramPacket dp = new DatagramPacket(b,b.length,InetAddress.getByName("127.0.0.1"),10001);ds.send(dp);}ds.close();}
}
(**)接收端需要进行while(true),接收端的连接不用关闭
import java.net.DatagramPacket;
import java.net.DatagramSocket;//接收端
public class ReciveClass {public static void main(String[] args) throws Exception{//指明用哪个端口接收DatagramSocket ds = new DatagramSocket(10001);//接收端一般就是一直的while(true)while(true){byte[] b = new byte[1024];DatagramPacket dp = new DatagramPacket(b,b.length);ds.receive(dp);//打印接收到的发送端的数据String ip = dp.getAddress().getHostAddress();//打印发送端的ipString data = new String(dp.getData(),0,dp.getLength());//打印发送端的数据int port = dp.getPort();//打印发送端的端口System.out.println("ip:"+ip+",data:"+data+",port:"+port);   }}
}

使用线程键盘发送数据的例子:(注意:是单独的程序)

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class Send implements Runnable {DatagramSocket ds = null;public Send(DatagramSocket ds){this.ds = ds;}@Overridepublic void run() {try{BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String line = null;while((line = br.readLine())!= null){//readLine是一个阻塞式的方法if("over".equals(line)){//但是发送端结束了,接收端还会一直接收,阻塞着break;}byte[] b = line.getBytes();DatagramPacket dp = new DatagramPacket(b,b.length,InetAddress.getByName("127.0.0.1"),10002);ds.send(dp);}}catch(Exception e){throw new RuntimeException("发送端失败");}finally{ds.close();}}}
import java.net.DatagramPacket;
import java.net.DatagramSocket;public class Recive implements Runnable {DatagramSocket ds = null;public Recive(DatagramSocket ds){this.ds = ds;}@Overridepublic void run() {try{while(true){byte[] b = new byte[1024];DatagramPacket dp = new DatagramPacket(b,b.length);ds.receive(dp);//打印接收到的发送端的数据String ip = dp.getAddress().getHostAddress();//打印发送端的ipString data = new String(dp.getData(),0,dp.getLength());//打印发送端的数据int port = dp.getPort();//打印发送端的端口System.out.println("ip:"+ip+",data:"+data+",port:"+port);   }}catch(Exception e){throw new RuntimeException("接收端失败");}}}
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Test{public static void main(String[] args) throws Exception {DatagramSocket sendS = new DatagramSocket();//发送端与接收端使用的Socket是不同的,两端各自有一个DatagramSocket reciveS = new DatagramSocket(10002);new Thread(new Send(sendS)).start();new Thread(new Recive(reciveS)).start();}
}

4.TCP传输

(1)需要客户端和服务端,是两个独立的程序。客户端使用Socket,服务端使用ServerSocket。通过Socket中的IO进行数据传输。

(2)客户端需要指明服务端接收端的Ip与端口号。服务端需要指明接受的端口号。

(3)接受的服务端可以得到客户端的ip

(4)通过Socket可以得到 InputStream和OutputStream

(5)先启动服务端,然后启动客户端

客户端发送,服务端接收:

import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class TcpServer {public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10003);Socket s = ss.accept();//获得客户端的SocketString ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connection");InputStream in = s.getInputStream();byte[] b = new byte[1024];int count = in.read(b);String str = new String(b,0,count);System.out.println(str);//只关闭Socket和ServerSockets.close();ss.close();}
}
import java.io.OutputStream;
import java.net.Socket;//客户端
public class TcpClient {public static void main(String[] args) throws Exception{//指明目的的ip和端口Socket s = new Socket("127.0.0.1",10003);OutputStream os = s.getOutputStream();os.write("hello".getBytes());//只关闭Sockets.close();}
}

客户端与服务端互相读写:

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class TcpServer {public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10004);Socket s = ss.accept();//获得客户端的SocketString ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connection");//读取InputStream in = s.getInputStream();byte[] b = new byte[1024];int count = in.read(b);String str = new String(b,0,count);System.out.println("服务端接收的数据:"+str);OutputStream out = s.getOutputStream();out.write("这是服务端写的数据".getBytes());//只关闭Socket和ServerSockets.close();ss.close();}
}
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;//客户端
public class TcpClient {public static void main(String[] args) throws Exception{//指明目的的ip和端口Socket s = new Socket("127.0.0.1",10004);//写过去OutputStream os = s.getOutputStream();os.write("这是客户端写的数据".getBytes());//进行读取InputStream in = s.getInputStream();byte[] b = new byte[1024];int count = in.read(b);String str = new String(b,0,count);System.out.println("从服务端读到的数据:"+str);//只关闭Sockets.close();}
}

使用Buffered提高效率,从键盘读取,客户端与服务端进行数据读写:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;public class TcpServer {public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10005);Socket s = ss.accept();//获得客户端的SocketString ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connection");//读取,从客户端读取BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//写,写入客户端BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));String str = null;while((str = br.readLine())!= null){bw.write(str.toUpperCase());//注意:下面的两行一定要写,因为readLine没有换行符bw.newLine();bw.flush();}//不需要关闭流//只关闭Socket和ServerSockets.close();ss.close();}
}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;//客户端
public class TcpClient {public static void main(String[] args) throws Exception{//指明目的的ip和端口Socket s = new Socket("127.0.0.1",10005);//从键盘读BufferedReader brJian = new BufferedReader(new InputStreamReader(System.in));    //写过去,写到服务端去BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));   //读取,从服务端读取BufferedReader brFu = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null;while((line = brJian.readLine())!=null){//控制从键盘读取会结束的if("over".equals(line)){break;}bw.write(line);//注意:下面的两行一定要写,因为readLine没有换行符bw.newLine();bw.flush();//注意:从服务端读是写在这里的,写在了while中,实时通讯String str = brFu.readLine();System.out.println("客户端读到的数据:"+str);}//只关闭Sockets.close();//关闭键盘读取的流brJian.close();}
}

使用PrintWriter,优于Buffered:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;public class TcpServer {public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10005);Socket s = ss.accept();//获得客户端的SocketString ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connection");//读取,从客户端读取BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//写,写入客户端//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));PrintWriter bw = new PrintWriter(s.getOutputStream());String str = null;while((str = br.readLine())!= null){bw.println(str.toUpperCase());bw.flush();//需要刷新//也可以在创建PrintWriter的时候指明会自动刷新}//不需要关闭流//只关闭Socket和ServerSockets.close();ss.close();}
}import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;//客户端
public class TcpClient {public static void main(String[] args) throws Exception{//指明目的的ip和端口Socket s = new Socket("127.0.0.1",10005);//从键盘读BufferedReader brJian = new BufferedReader(new InputStreamReader(System.in));//写过去,写到服务端去//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));PrintWriter bw = new PrintWriter(s.getOutputStream());//读取,从服务端读取BufferedReader brFu = new BufferedReader(new InputStreamReader(s.getInputStream()));String line = null;while((line = brJian.readLine())!=null){//控制从键盘读取会结束的if("over".equals(line)){break;}bw.println(line);bw.flush();//注意:从服务端读是写在这里的,写在了while中,实时通讯String str = brFu.readLine();System.out.println("客户端读到的数据:"+str);}//只关闭Sockets.close();//关闭键盘读取的流brJian.close();}
}

上面程序可能存在的问题:客户端从键盘读,有结束的时候,写过去有结束的时候,但是服务端读没有结束的时候,就会造成阻塞。后面讲解决的办法。

文件复制(Buffered、PrintWriter):

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;public class TcpServer {public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10006);Socket s = ss.accept();//获得客户端的SocketString ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connection");//读取,从客户端读取BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//写,写入客户端PrintWriter bw = new PrintWriter(s.getOutputStream(),true);//写入文件,文件不存在的时候会自动的创建PrintWriter pw = new PrintWriter(new FileWriter("C:\\Users\\huer\\Desktop\\b.txt"),true);String str = null;while((str = br.readLine())!= null){pw.println(str);    }//这里需要写在循环的外面bw.println("服务端说:上传成功");//不需要关闭流//只关闭Socket和ServerSockets.close();ss.close();pw.close();}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;//客户端
public class TcpClient {public static void main(String[] args) throws Exception{//指明目的的ip和端口Socket s = new Socket("127.0.0.1",10006);//从文件读BufferedReader brJian = new BufferedReader(new FileReader("C:\\Users\\huer\\Desktop\\a.txt"));//写过去,写到服务端去PrintWriter bw = new PrintWriter(s.getOutputStream(),true);//读取,从服务端读取BufferedReader brFu = new BufferedReader(new InputStreamReader(s.getInputStream()));String line = null;//从文件读取while((line = brJian.readLine())!=null){         bw.println(line);           }//这个是写在循环外的String str = brFu.readLine();System.out.println("客户端读到的数据:"+str);//只关闭Sockets.close();//关闭文件流brJian.close();}
}

读写都是对应着的。

分析存在的问题:客户端从文件读,有结束的时候,所以写到服务端有结束的时候,但是服务端还在一直等着接收客户端传过来的数据,会一直等着,不知道什么时候结束,所以服务端存在方法阻塞的情况。

shutdownOutput()方法解决方法阻塞:

客户端写结束的时候,指明结束写

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;public class TcpServer {public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10006);Socket s = ss.accept();//获得客户端的SocketString ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connection");//读取,从客户端读取BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//写,写入客户端PrintWriter bw = new PrintWriter(s.getOutputStream(),true);//写入文件,文件不存在的时候会自动的创建PrintWriter pw = new PrintWriter(new FileWriter("C:\\Users\\huer\\Desktop\\b.txt"),true);String str = null;while((str = br.readLine())!= null){pw.println(str);    }//这里需要写在循环的外面bw.println("服务端说:上传成功");//不需要关闭流//只关闭Socket和ServerSockets.close();ss.close();pw.close();}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;//客户端
public class TcpClient {public static void main(String[] args) throws Exception{//指明目的的ip和端口Socket s = new Socket("127.0.0.1",10006);//从文件读BufferedReader brJian = new BufferedReader(new FileReader("C:\\Users\\huer\\Desktop\\a.txt"));//写过去,写到服务端去PrintWriter bw = new PrintWriter(s.getOutputStream(),true);//读取,从服务端读取BufferedReader brFu = new BufferedReader(new InputStreamReader(s.getInputStream()));String line = null;//从文件读取while((line = brJian.readLine())!=null){         bw.println(line);           }s.shutdownOutput();//指明结束写//这个是写在循环外的String str = brFu.readLine();System.out.println("客户端读到的数据:"+str);//只关闭Sockets.close();//关闭文件流brJian.close();}
}

下面是一个解决方法阻塞的例子:

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class TcpServer {public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10007);Socket s = ss.accept();String ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connection");FileOutputStream fo = new FileOutputStream("C:\\Users\\huer\\Desktop\\图片\\2.jpg");//从文件读,上传到另一个图片byte[] b = new byte[1024];int len = 0;InputStream in = s.getInputStream();while((len = in.read(b))!=-1){fo.write(b, 0, len);}OutputStream oos = s.getOutputStream();oos.write("上传成功".getBytes());s.close();ss.close();fo.close();}
}
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;//客户端
public class TcpClient {public static void main(String[] args) throws Exception{Socket s = new Socket("127.0.0.1",10007);//文件FileInputStream fi = new FileInputStream("C:\\Users\\huer\\Desktop\\图片\\1.jpg");OutputStream os = s.getOutputStream();//从文件读,写过去byte[] b = new byte[1024];int len = 0;while((len = fi.read(b))!=-1){//读文件有结束的时候,所以写过去有结束的时候,但是服务端不知道,所以下面用shutdownOutput指明写入结束os.write(b, 0, len);}s.shutdownOutput();//关闭输出流//从服务端读,打印出来InputStream in = s.getInputStream();byte[] bin = new byte[1024];int blen = 0;blen = in.read(bin);System.out.println(new String(bin,0,blen));//关闭连接和文件流s.close();fi.close();}
}

使用线程实现TCP传输:

思路:服务端的ServerSocket只能初始化一次,然后只要有一个客户端连接上来,就有一个Socket,就启动一个线程。

服务端ServerSocket不用关闭。

使用线程实现图片文件上传。客户端从本地文件一直读取图片并上传至服务端,服务端将读取到的图片保存起来。

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class PicServer {public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10007);//允许多个人连接进来,使用whilewhile(true){Socket s = ss.accept();new Thread(new PicThread(s)).start();}//ss.close();//不用进行关闭}
}
class PicThread implements Runnable{private Socket s;PicThread(Socket s){this.s = s;}@Overridepublic void run() {int count = 1;String ip = s.getInetAddress().getHostAddress();try{System.out.println(ip+"....connection");//用File封装一下//File f = new File("C:\\Users\\huer\\Desktop\\图片\\2.jpg");File f = new File("C:\\Users\\huer\\Desktop\\图片\\"+ip+"("+count+")"+".jpg");//这是避免文件名覆盖if(f.exists()){//这里使用的是++count,不要使用count++f = new File("C:\\Users\\huer\\Desktop\\图片\\"+ip+"("+(++count)+")"+".jpg");}System.out.println(count);FileOutputStream fo = new FileOutputStream(f);//不存在的时候会自动创建//从文件读,上传到另一个图片byte[] b = new byte[1024];int len = 0;InputStream in = s.getInputStream();while((len = in.read(b))!=-1){fo.write(b, 0, len);}OutputStream oos = s.getOutputStream();oos.write("上传成功".getBytes());s.close();fo.close();}catch(Exception e){throw new RuntimeException(ip+"上传文件失败");}}}
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;//客户端
public class TcpClient {public static void main(String[] args) throws Exception{Socket s = new Socket("127.0.0.1",10007);//关于图片的路径需要重新修改,现在先不管,测试的话是有问题的if(args.length!=1){System.out.println("请选择一个jpg格式的图片");return;}File f = new File(args[0]);if(!(f.exists() && f.isFile())){System.out.println("该文件有问题,要么不存在,要么不是文件");return;}if(!(f.getName().endsWith(".jpg"))){System.out.println("图片格式错误,请重新选择");return;}if(f.length()>1024*1024*5){System.out.println("文件过大,重新选择");return;}//文件FileInputStream fi = new FileInputStream(f);OutputStream os = s.getOutputStream();//从文件读,写过去byte[] b = new byte[1024];int len = 0;while((len = fi.read(b))!=-1){os.write(b, 0, len);}s.shutdownOutput();//关闭输出流//从服务端读,打印出来InputStream in = s.getInputStream();byte[] bin = new byte[1024];int blen = 0;blen = in.read(bin);System.out.println(new String(bin,0,blen));//关闭连接和文件流s.close();fi.close();}
}

用户登录次数限制:

思路:用户最多进行三次的尝试登陆,服务端也只进行三次的测试登陆,所以有一个for循环。for循环有结束控制的条件,所以不需要使用shutdownOutput()

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;public class PicServer {public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10008);while(true){Socket s = ss.accept();new Thread(new PicThread(s)).start();}}
}
class PicThread implements Runnable{private Socket s;PicThread(Socket s){this.s = s;}@Overridepublic void run() {int count = 1;String ip = s.getInetAddress().getHostAddress();try{System.out.println(ip+"....connection");BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));PrintWriter pw = new PrintWriter(s.getOutputStream(),true);   for(int i=1;i<=3;i++){//这里是非常要注意的点:在循环里面,每次都要重新的打开用户名的文件,操作完一次之后就要进行关闭//所以brFile的创建要在for中,brFile的关闭也要在for中BufferedReader brFile = new BufferedReader(new FileReader("C:\\Users\\huer\\Desktop\\user.txt"));String name = br.readLine();if(name == null){break;}System.out.println(name);boolean f = false;String line = null;while((line =brFile.readLine())!=null){System.out.println("服务端从文件中读到的数据:"+line);if(line.equals(name)){f = true;break;}}if(f){System.out.println(name+"已登陆");pw.println(name+"欢迎登陆");break;//停止服务端的for循环}else{System.out.println(name+"尝试登陆");pw.println(name+"用户名不存在");}brFile.close();}s.close();}catch(Exception e){throw new RuntimeException(ip+"校验失败");}}}
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;//客户端
public class TcpClient {public static void main(String[] args) throws Exception{Socket s = new Socket("127.0.0.1",10008);BufferedReader brJian = new BufferedReader(new InputStreamReader(System.in));//从键盘读BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//从服务端读PrintWriter pw = new PrintWriter(s.getOutputStream(),true);//向服务端写//只允许用户操作3次for(int i=1;i<=3;i++){String line = brJian.readLine();//防止方法 的阻塞if(line == null){break;}pw.println(line);String str = br.readLine();System.out.println("从服务端读取的信息:"+str);//登陆成功之后就退出循环if(str.contains("欢迎")){break;//如果读到欢迎登陆了,客户端就停止for循环}}s.close();brJian.close();}
}

浏览器-自定义服务端,访问的时候:192.168.159.10:11000,注意ip不要写loacalhost,不要写127.0.0.1:

服务端:

public class ServerDemo {public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(11000);Socket s = ss.accept();String ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connection");//这里就是简单的测试//客户端连接上服务端之后,发送给客户端,"客户端你好"PrintWriter pw = new PrintWriter(s.getOutputStream(),true);//pw.println("<font color='red' size='7'>客户端,你好</font>");pw.println("客户端,你好");s.close();ss.close();}
}

浏览器-自定义服务端,服务端读取浏览器传递过来的消息头,然后给浏览器写过去一些数据:

import java.io.InputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;public class ServerDemo {public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(11000);Socket s = ss.accept();String ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connection");//输出一下从浏览器读过来的信息头InputStream in = s.getInputStream();byte[] b = new byte[1024];int len = 0;len = in.read(b);String str = new String(b,0,len);System.out.println("从浏览器读到的数据:"+str);PrintWriter pw = new PrintWriter(s.getOutputStream(),true);pw.println("<font color='red' size='7'>客户端,你好</font>");//pw.println("客户端,你好");s.close();ss.close();}
}
从浏览器读到的数据:GET / HTTP/1.1
Host: 192.168.159.10:11000(这里就相当于客户端的Socket)
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,en-US;q=0.8,zh;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1

自定义浏览器-自定义服务器,就是客户端写过去的数据首先写头消息,然后读服务端返回的数据:

自定义浏览器就是:写过去头消息,然后是数据:

import java.io.InputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;//自定义服务器
public class ServerDemo {public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(11000);Socket s = ss.accept();String ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connection");//输出一下从浏览器读过来的信息头InputStream in = s.getInputStream();byte[] b = new byte[1024];int len = 0;len = in.read(b);String str = new String(b,0,len);System.out.println("从浏览器读到的数据:"+str);PrintWriter pw = new PrintWriter(s.getOutputStream(),true);pw.println("<font color='red' size='7'>客户端,你好</font>");//pw.println("客户端,你好");s.close();ss.close();}
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;//自定义浏览器
public class MyIE {public static void main(String[] args) throws Exception{Socket s = new Socket("192.168.159.10",11000);PrintWriter pw = new PrintWriter(s.getOutputStream(),true);pw.println("GET / HTTP/1.1");//"/"是请求的路径pw.println("Accept: */*");pw.println("Accept-Language: zh-CN");pw.println("Host: 192.168.159.10:11000");pw.println("Connection: keep-alive");pw.println("Connection: closed");//下面的两行是固定的格式pw.println();pw.println();BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));String line = null;line=br.readLine();System.out.println(line);s.close();}
}

URL

封装浏览器访问的url,表示统一资源定位符。

public static void main(String[] args) throws Exception {URL url = new URL("http://192.168.159.10:11000/myweb/test.html?name=zhangsan&age=20");System.out.println(url.getProtocol());//httpSystem.out.println(url.getHost());//192.168.159.10if(url.getPort() == -1){String port = "11000";}System.out.println(url.getPort());//11000System.out.println(url.getPath());//  /myweb/test.htmlSystem.out.println(url.getFile());//  /myweb/test.html?name=zhangsan&age=20System.out.println(url.getQuery());//  name=zhangsan&age=20}

URLConnection

URLConnection表示URL所引用的远程对象的连接。url.openConnection()。每次调用这个方法都会得到一个新的连接。

public static void main(String[] args) throws Exception {URL url = new URL("http://192.168.159.10:11000/myweb/test.html");URLConnection connection = url.openConnection();System.out.println(connection);InputStream in = connection.getInputStream();OutputStream out = connection.getOutputStream();//进行读写.....}

java基础-网络编程相关推荐

  1. JAVA基础 网络编程

    JAVA基础 网络编程 网络我们每天都会用到的,在我们生活中占的地位也在不断的提高,我们下面就简单了解下网络编程的内容. 想要学习网络编程,首先就需要了解网络编程包含哪些内容. 网络编程包括 IP节点 ...

  2. 学习笔记-java基础-网络编程

    刚在培训机构学习完JAVA基础和WEB,感觉边学边忘.就把这作为记忆的笔记,我也不知道要不要记笔记,写在本子上太耗费时间了. 一.要想实现网络通信,首先要解决两个问题: ①:如何从网络中定位到一台或多 ...

  3. 黑马程序员——java基础---网络编程

    ------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS ...

  4. java基础网络编程

    利用网络,实现两台计算机之间的互相联通.交互. 网络编程有两类: UDP 一种无连接的传输层协议.无连接:指不需要知道对方在不在,只负责发数据传输出去,而对方可能不在,数据便会丢失,所以是不稳定的. ...

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

    ------- android培训.java培训.期待与您交流! ---------- 网络编程1 一.获取IP     网络编程主要在传输层 :TCP(Transmission Control Pr ...

  6. Java基础(网络编程基础)

    1.软件结构 C/S:客户端和服务器(QQ.微信) B/S:浏览器和服务器(火狐.IE.谷歌) 2.网络通信协议 网络通信协议: 通过计算机网络可以使多台计算机实现连接,位于同一个网络中的计算机在进行 ...

  7. Java基础——网络编程

    一.网路编程知识 意义:过去我们IO流是把本地的文件传递而已,网络编程是把自己电脑的数据传递给另一台电脑,并且回馈信息.这是数据通讯 1.通讯三要素 1.1 IP地址 (1)获取对方主机IP 1.2 ...

  8. IT十八掌Java基础 网络编程

    网络编程 计算机网络 是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统. 网 ...

  9. java基础----网络编程

    网络编程 1.什么是网络?网络模型?网络四要素? 网络: 在计算机领域中网络是信息传输,接收,共享的虚拟平台,通过它把各个点,面,体的联系到一起,从而实现这些资源的共享. 网络模型: 计算机网络是指由 ...

最新文章

  1. 九州云陈沙克:OpenStack的成功源于自身的开放
  2. 一年拿下软考中高级+PMP是一种怎样的体验?
  3. python常用函数和操作_python一条语句分析几个常用函数和概念 -
  4. 计算机系统操作技师考试题,机关事业单位技术工人计算机操作技师考试题库
  5. Message:Unable to locate element 问题解决方法
  6. android虚拟机的使用教程,Android 虚拟机可以这么用了 ?
  7. xmlObj转为数组
  8. Learning Moodle 3.5 学习Moodle 3.5 Lynda课程中文字幕
  9. 电商项目中遇到的经典问题
  10. JDK1.8API文档中文版和英文版下载
  11. 更新到PS CC 2019 缩放的时候 按住shift变成不规则缩放了 反而不按住shift是等比例缩放...
  12. python写Bicubic方法,跑数据集Set5和Set14,保存PSNR和SSIM的值
  13. JavaScript 技术篇-js正则表达式匹配中英文数字
  14. 【开源工程】VirtualDub
  15. 计算机网络技术与应用张基温答案,计算机网络技术与应用教程张基温杜勇刘诗瑾廖伟国董兆军第3章接入技术课件教学.ppt...
  16. python登陆百度网盘并读取自己的所有文件,输出到文本文件中
  17. 5G 空口信令分析指导书
  18. Labview Socket通讯_通讯板卡
  19. 从简单的信道估计说起
  20. iPad2越狱后如何安装常用软件

热门文章

  1. ShaderToy 转换到 Unity中(超级方便的一个工具)
  2. return 不能跳出 forEach 循环
  3. MicrosoftExcel函数
  4. 计算机SCI期刊是如何审稿的? - 易智编译EaseEditing
  5. UNIX和Linux Shell正则表达式语法介绍
  6. python装饰器带参数函数二阶导数公式_SICP Python 描述 1.6 高阶函数
  7. 【推荐】mysql联合 索引(复合索引)的探讨
  8. DevOps之不中断服务的蓝绿部署
  9. 使用 acme.sh 签发 SSL证书失败
  10. 转:网络带宽测量工具之iperf