Java基础之网络编程知识点总结
2014-12-01 22:00
666 查看
Java语言涵盖的领域很广,对于网络方面,java也是相当棒的,java也是可以完成网络通讯的功能的。想想看,原来我们写出来的java代码都是单机版的,只能一个人在操作,而现在我们想实现这样一个功能,从我的机器上发出一条信息到张三的机器上,然后,张三再给我回复一条信息发到我的机器上。 实际上我们知道数据通讯的原理就是数据的传输的过程。 网络模型: 1.OSI参考模型 2.TCP/IP参考模型 网络通信要素: 1. IP地址 2. 端口号 3. 传输协议 试想,要想给张三通讯首要要做的就是找到张三的那台主机,那么怎么找,通过什么方法完成两台机器的通讯呢? 步骤:1)找到对方的IP 2)数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识,为了方便称呼这个数字,就叫做端口。 注意:这里的端口不是物理机器上的实际的端口,而是逻辑端口。 3)定义一个通讯规则。这个通讯规则称为协议。 国际组织定义了一个通用的协议--TCP/IP协议。
网络通信的要素: IP地址:InetAddress 特点: 网络中的设备标识。 不易记忆,但是可用主机名。 本地回环地址127.0.0.1 主机名localhost。
例子1:获得本机的IP地址和主机名。
package cn.itheima.day06; import java.net.InetAddress; import java.net.UnknownHostException; public class IPDemo { public static void main(String[] args) throws UnknownHostException { InetAddress i = InetAddress.getLocalHost(); //getLocalHost()返回本地主机 //System.out.println(i.toString()); //System.out.println("address::"+i.getHostAddress()); //获取IP地址 //System.out.println("name::"+i.getHostName()); //获取主机名 InetAddress ia = InetAddress.getByName("127.0.0.1"); System.out.println("address::"+ia.getHostAddress()); //获取IP地址 System.out.println("name::"+ia.getHostName()); //获取主机名 } }
端口号: 特点: 用于标识进程的逻辑地址。 有效端口号:0—65535,其中0—1024系统使用或保留端口。 传输协议:通讯的规则。 常见协议:TCP、UDP。 TCP和UDP两者之间的区别: UDP:1)将数据及源和目的封装成数据包中,不需要建立连接。 2)每个数据包的大小要限制在64k内 3)因无连接,是不可靠协议的。 4)不需要建立连接,速度快。 UDP就像生活中去寄包裹类似:物品—包装—贴物流单(填写发送信息:IP+端口)--但是填写的地址可能不存在,所以有可能就丢弃了。 UDP:飞秋聊天、凌波桌面共享、网络视频会议 TCP:1)建立连接,形成传输数据的通道。 2)在连接中进行大数据量传输。 3)通过三次握手完成连接,是可靠协议。 4)必须建立连接,效率会稍低。 TCP就像生活中的打电话:拨号—连接(发连接请求)--连接通路,然后双方说话。 TCP:在线下载、打电话 Socket: Scoket就是为网络服务提供的一种机制。通信的两端都有Socket。网络通信其实就是Socket间的通信。 数据在两个Socket间通过IO传输。 UDP传输(建立UDP的Socket服务方法): 1)DatagramSocket与DatagramPacket. 2)建立发送端,接收端。 3)建立数据包。 4)调用Socket的发送接收方法。 5)关闭Socket。 注意:发送端和接收端是两个独立的运行程序。
例子2.定义一个Socket的发送端和接收端,用于实现两个程序间的发送消息。 定义了一个udp的发送端:
package cn.itheima.day06; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /** * 通过udp传输方式,讲一段文字数据发送出去。 * 定义了一个udp的发送端。 * @author wl-pc * 思路:1.建立udpsocket服务。 * 2.要提供数据,并将数据封装到数据包中。 * 3.通过socket服务的发送功能,将数据包发送出去。 * 4.关闭资源 */ public class UdpSendDemo { public static void main(String[] args) throws IOException { //1.创建udp服务,通过DatagramScoket对象。 DatagramSocket ds = new DatagramSocket(8888); //2.确定数据,并且封装成数据包 byte[] buf = "itheima,hello!".getBytes(); DatagramPacket dp =new DatagramPacket(buf, buf.length,InetAddress.getByName("127.0.0.1"),10000); //3.通过socket服务,将已有的数据包发送出去,通过send()方法 ds.send(dp); //关闭资源 ds.close(); } }
定义了一个udp的接收端:
package cn.itheima.day06; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; /** * 定义一个应用程序,用于接收Udp协议传输的数据并处理数据。 * @author wl-pc * 思路: * 1.定义udpsocket服务。(注意:在定义udp的接收端)通常 * 都会监听一个端口,其实就是给这个接收网络应用程序定义 * 一个数字标识,方便与明确哪些数据过来,该应用程序可以处理。 * 2.定义一个数据包,因为要存储接收到的字节数据,因为数据 * 包对象中,有更多功能可以提取字节数据中的不同数据信息 * 3.通过socket服务的receive()方法接收到数据存入已定义好 * 的数据包中。 * 4.通过数据包对象的特有的功能,将这些不同的数据取出,打 * 印到控制台上 * 5.关闭资源。 */ public class UdpReceDemo { public static void main(String[] args) throws IOException { //1.创建udp的socket服务,建立端点 DatagramSocket ds = new DatagramSocket(10000); //2.定义数据包,用于存储数据。 byte[] buf = new byte[1024]; DatagramPacket dp =new DatagramPacket(buf, buf.length); //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(); } }
例子3:聊天小程序 定义了一个udp的发送端:
package cn.itheima.day06; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /** * 记着一个规律:在程序中只要用到了java.net包,通常都会用到java.io包。 * @author wl-pc*/ public class UdpSendDemo2 { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line = null; //readLine()方法是阻塞式方法,如果没有数据,会等 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"),10003); ds.send(dp); } ds.close(); } }
定义了一个udp的接收端:
package cn.itheima.day06; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UdpReceDemo2 { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(10003); while(true){ byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); ds.receive(dp); //receive()方法是阻塞式方法,如果没有数据,会等 String ip = dp.getAddress().getHostAddress(); String data = new String(dp.getData(),0,dp.getLength()); int port = dp.getPort(); System.out.println(ip+"::"+data+"::"+port); } } }
例子3:使用多线程的技术完成聊天小程序。(1个进程多个线程)
package cn.itheima.day06; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; /** * 编写一个聊天程序: * 有一个接收数据的部分和发送数据的部分, * 这两个部分需要同时执行,那就要使用到了 * 多线程技术了,一个线程控制接收数据, * 另一个线程负责发送数据。 * @author wl-pc * 因为收和发数据的动作时不一致的,所以 * 要定义两个run()方法,而且这两个run() * 方法要封装到不同的类中。 */ class Send implements Runnable{ private DatagramSocket ds; Send(DatagramSocket ds) { this.ds = ds; } @Override public void run() { try { 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"),10005); ds.send(dp); } } catch (Exception e){ throw new RuntimeException("发送端失败!"); } } } class Rece implements Runnable{ private DatagramSocket ds; Rece(DatagramSocket ds) { this.ds = ds; } @Override 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()); int port = dp.getPort(); System.out.println(ip+"::"+data+"::"+port); } } catch (Exception e) { throw new RuntimeException("接收端失败!"); } } } public class ChatDemo { public static void main(String[] args) throws SocketException { DatagramSocket sendSocket = new DatagramSocket(); DatagramSocket receSocket = new DatagramSocket(10005); new Thread(new Send(sendSocket)).start(); new Thread(new Rece(receSocket)).start(); } }
TCP传输: 1)Socket和ServerSocket 2)建立客服端和服务器端 3)建立连接后,通过Socket中的IO流进行数据的传输。 4)关闭socket 同样,客户端与服务器端是两个独立的应用程序。
例子4:客户端向服务端发送数据信息。 定义了一个TCP的服务器端:
package cn.itheima.day06; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; /** * 服务端需求:定义端点接收数据,并且打印到控制台上。 * 步骤: * 1)建立服务端的socket的服务,通过ServerSocket()来建立, * 并监听一个端口。 * 2)获取连接过来的客户端对象,通过ServerSocket的accept() * 方法来完成。所以这个方法是阻塞式的,没有连接,就会等。 * 3)客户端如果发过来数据,那么服务端要使用对应的客户端对象 * 并获取到该客户端对象的读取流来读取的发过来的数据。并打印 * 在控制台上。 * 4)(可选操作)关闭服务端。 */ public class TcpServer { public static void main(String[] args) throws IOException{ //1.建立服务端的socket服务,并监听一个端口 ServerSocket ss = new ServerSocket(10006); //2.通过accept()方法获取连接过来的客户端对象。 Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+"::连接成功!"); //3.获取客户端发送过来的数据,那么要使用客户 //端对象的读取流来读取数据 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的客户端:
package cn.itheima.day06; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; /** * 演示TCP传输: * @author wl-pc * 1.tcp分为客户端和服务器端 * 2.客服端对应的对象是socket * 服务器端对应的对象是serverSocket */ /** * 客户端:通过查阅socket对象,发现在该 * 对象建立时,就可以连接指定的主机。 * 因为tcp是面向连接的。所以在建立socket服务 * 时,就要有服务端存在,并且连接成功,形成 * 通路后,再在该通道进行数据的传输。 * @author wl-pc * 步骤: * 1)创建socket服务,并指定要连接的主机和端口 * 2)为了发送数据,应该获取socket流中的输出流 * 3)往输入流中写数据 * 4)关闭资源 */ /** * 需求:给服务端发送一个文本数据 */ public class TcpClient { public static void main(String[] args) throws UnknownHostException, IOException { //1.创建客户端的socket服务,指定目的主机以及端口 Socket s = new Socket("127.0.0.1",10006); //2.为了发送数据,应该获取socket流中的输出流 OutputStream out = s.getOutputStream(); //3.往流中写数据 out.write("itheima,hello!".getBytes()); //4.关闭资源 s.close(); } }
例子5:演示tcp的传输的客户端和服务器端的互访。 定义了一个TCP的服务器端:
package cn.itheima.day06; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /** * 演示tcp的传输的客户端和服务器端的互访。 * @author wl-pc */ public class TcpServer2 { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(10007); Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+"......conneted"); 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("收到数据,你也好!".getBytes()); s.close(); ss.close(); } }
定义了一个TCP的客户端:
package cn.itheima.day06; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; /** * 演示tcp的传输的客户端和服务器端的互访。 * @author wl-pc * 需求是:客户端给服务端发送数据,服务器 * 端收到数据后,给客户端反馈信息 */ /** * 客户端步骤: * 1)建立socket服务,指定要连接的主机和端口 * 2)获取socket流中输出流,将数据写到该流中 * 通过网络发送到服务器端 * 3)获取socket流中输入流,将服务端反馈的数 * 据获取到并打印到控制台上 * 4)关闭客户端资源 */ public class TcpClient2 { public static void main(String[] args) throws UnknownHostException, IOException { Socket s = new Socket("127.0.0.1",10007); OutputStream out =s.getOutputStream(); out.write("服务端,你好".getBytes()); InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); System.out.println(new String(buf,0,len)); s.close(); } }
例子6:建立一个文本转换服务器,客户端给服务器端发送文本,然后服务器端将文件转成大写,再返回给客户端,而且客服端可以不断的进行文本转换,当客户端输入over时转换就结束了。 定义了一个TCP的服务器端:
package cn.itheima.day06; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; /** * 服务端: * 源:socket读取流 * 目的:socket输出流 * @author wl-pc * 都是文本数据并且需要装饰 */ public class TransServer { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(4002); Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+"....conneted"); //读取socket读取流中的数据 BufferedReader bufIn =new BufferedReader(new InputStreamReader(s.getInputStream())); //socket输出流中,并且要转换成大写字母再写入到socket输出流,并发送给客户端 BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line = null; while((line=bufIn.readLine())!=null){ //readLine()阻塞式方法 bufOut.write(line.toUpperCase()); bufOut.newLine(); //跨平台换行 bufOut.flush(); //刷新数据 } s.close(); ss.close(); } }
定义了一个TCP的客户端:
package cn.itheima.day06; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; /** * 需求:建立一个文本转换服务器 * 客户端给服务器端发送文本,然后服务器端将文件转成大写 * 再返回给客户端,而且客服端可以不断的进行文本转换,当 * 客户端输入over时转换就结束了 * @author wl-pc * 分析: * 客服端: * 既然是操作设备上的数据,就可以使用IO技术,按照IO的操作 * 规律来思考,对于客服端来讲,源:键盘录入。 * 目的:网络设备(网络输出流),而且操作的是文本数据, * 是文本数据可以选择字符流, * 步骤: * 1)建立服务。 * 2)获取键盘录入。 * 3)将数据发给服务端。(重复操作) * 4)获取服务端返回的大写数据。(重复操作) * 5)结束,关闭资源。 * 都是文本数据,可以用字符流进行操作。 * 同时为了提高效率,加入了缓冲技术 */ public class TransClient { public static void main(String[] args) throws IOException { Socket s = new Socket("127.0.0.1",4002); //定义读取键盘数据的流对象 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); //定义目的,将数据写入到socket输出流中,发给服务端 BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); //定义一个socket读取流,读取服务端反馈的大写信息 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null; while((line=bufr.readLine())!=null){ if("over".equals(line)) break; //往服务器端写入要转换的信息 bufOut.write(line); bufOut.newLine(); bufOut.flush(); //刷新数据 //读出转换后的大写信息 String str = bufIn.readLine(); System.out.println("server::"+str); } bufr.close(); s.close(); } } /** * 该例子出现的问题。 * 现象:客户端和服务端都在莫名的等待,这是为什么? * 因为客户端和服 务器端都有阻塞式的方法,这些方法没有 * 读到结束标记,那么就一直等,而导致两端,都在等待, * 解决方法:就查看阻塞式方法的地方,因为这个地方时 * 容易出错的地方。 */
例子7:上传文件到一个文件夹下。 定义了一个TCP的服务器端:
package cn.itheima.day06; import java.io.BufferedReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class TextServer { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(4006); Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+".....conneted"); BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); PrintWriter out = new PrintWriter(new FileWriter("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day06\\server.txt"),true); String line = null; while((line=bufIn.readLine())!=null){ out.println(line); } s.shutdownOutput(); //关闭客户端的输出流,相当于给流中加一个结束标记 :-1 PrintWriter pw = new PrintWriter(s.getOutputStream(),true); pw.println("上传成功!"); out.close(); s.close(); ss.close(); } }
定义了一个TCP的客户端:
package cn.itheima.day06; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; public class TextClient { public static void main(String[] args) throws UnknownHostException, IOException { Socket s = new Socket("127.0.0.1",4006); BufferedReader bufr = new BufferedReader(new FileReader("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day06\\client.txt")); PrintWriter out = new PrintWriter(s.getOutputStream(),true); //out.println(time); String line = null; while((line = bufr.readLine())!=null){ out.println(line); } BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); String str = bufIn.readLine(); System.out.println(str); bufr.close(); s.close(); } }
例子8:上传图片。 定义了一个TCP的服务器端:
package cn.itheima.day07; import java.io.FileOutputStream; import java.io.IOException; 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 IOException { ServerSocket ss = new ServerSocket(4007); Socket s = ss.accept(); InputStream in = s.getInputStream(); FileOutputStream fos = new FileOutputStream("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day07\\server.jpg"); byte[] buf = new byte[1024]; int len = 0; while((len=in.read(buf))!=-1){ fos.write(buf,0,len); } OutputStream out = s.getOutputStream(); out.write("上传成功!".getBytes()); fos.close(); s.close(); ss.close(); } }
定义了一个TCP的客户端:
package cn.itheima.day07; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; /** * 需求:上传图片 */ /** * 客户端: * 步骤: * 1)服务端点 * 2)读取客户端已有的一个图像数据 * 3)通过socket输出流将数据发给服务端 * 4)读取服务器端的反馈信息 * 5)关闭资源 */ public class PicClient { public static void main(String[] args) throws UnknownHostException, IOException { Socket s = new Socket("127.0.0.1",4007); FileInputStream fis = new FileInputStream("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day07\\1.jpg"); OutputStream out = s.getOutputStream(); byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf))!=-1){ out.write(buf,0,len); } s.shutdownOutput(); //告诉客户端数据已经写完 InputStream in =s.getInputStream(); byte[] bufIn = new byte[1024]; int num = in.read(bufIn); System.out.println(new String(bufIn,0,num)); fis.close(); s.close(); } }
例子9:改写例子8中的程序,要求多人可以上传图片到服务器端。 定义了一个TCP的服务器端:
package cn.itheima.day07; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /** * 这个服务端有个局限性:当A客户连接上时,被服务端获取到, * 服务端执行具体执行流程,这时B客户连接时,连不上,只有 * 等待,因为服务器端还没有处理完A的请求,还没有循环回来 * 执行下一次的accept()方法,所以暂时获取不到B客户对象。 * @author wl-pc * 那么为了可以让多个客户端同时并发访问服务端,那么服务端 * 最好是将每个客户端封装到一个单独的线程中,这样,就可以 * 同时处理多个客户端请求。 * * 那么如何定义线程呢? * 只要明确了每一个客户端要在服务端执行的代码即可,将代码 * 写在run()方法中即可。 */ class PicThread implements Runnable{ private Socket s; PicThread(Socket s) { this.s=s; } @Override public void run() { int count = 1; String ip = s.getInetAddress().getHostAddress(); try { System.out.println(ip+".....connected"); InputStream in = s.getInputStream(); File file = new File("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day07\\"+ip+"("+(count)+")"+".jpg"); while(file.exists()){ file = new File("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day07\\"+ip+"("+(count++)+")"+".jpg"); } FileOutputStream fos = new FileOutputStream(file); byte[] buf = new byte[1024]; int len = 0; while((len=in.read(buf))!=-1){ fos.write(buf,0,len); fos.flush(); } OutputStream out = s.getOutputStream(); out.write("上传成功!".getBytes()); fos.close(); s.close(); } catch (Exception e) { throw new RuntimeException(ip+"上传失败!"); } } } public class PicServer { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(4008); while(true){ //本意要实现多人上传图片到服务器端(但是此种方法是不可取的) Socket s = ss.accept(); //accept()是阻塞式方法 new Thread(new PicThread(s)).start(); //利用多线程实现同时上传的功能。 } //ss.close(); } }
定义了一个TCP的客户端:
package cn.itheima.day07; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException /** * 需求:上传图片 */ /** * 客户端: * 步骤: * 1)服务端点 * 2)读取客户端已有的一个图像数据 * 3)通过socket输出流将数据发给服务端 * 4)读取服务器端的反馈信息 * 5)关闭资源 */ public class PicClient { public static void main(String[] args) throws UnknownHostException, IOException { 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("上传的文件过大!"); return; } Socket s = new Socket("127.0.0.1",4008); FileInputStream fis = new FileInputStream(file); OutputStream out = s.getOutputStream(); byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf))!=-1){ out.write(buf,0,len); } s.shutdownOutput(); //告诉客户端数据已经写完 InputStream in =s.getInputStream(); byte[] bufIn = new byte[1024]; int num = in.read(bufIn); System.out.println(new String(bufIn,0,num)); fis.close(); s.close(); } }
例子10:用户登录的小例子。 需求:客户端通过键盘录入用户名,服务器端对这个用户名进行校验。如果该用户名存在,在服务器端显示xxxx,已登录。并在客户端显示xxx,欢迎光临。如果该用户不存在,在服务器端显示xxxx,尝试登陆。并在客户端显示xxxx,该用户不存在。最多登陆3次,3次后结束。 定义服务器端:
package cn.itheima.day07; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; class UserThread implements Runnable{ private Socket s; UserThread(Socket s){ this.s = s; } @Override public void run() { String ip =s.getInetAddress().getHostAddress(); System.out.println(ip+"....conneted"); try { for(int i=0;i<3;i++){ BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); String name = bufIn.readLine(); if(name==null) break; BufferedReader bufr = new BufferedReader(new FileReader("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day07\\user.txt")); PrintWriter out =new PrintWriter(s.getOutputStream(),true); String line = null; boolean flag = false; while((line=bufr.readLine())!=null){ if(line.equals(name)){ flag = true; break; } } if(flag){ System.out.println(name+",已经登陆!"); out.println(name+",欢迎光临"); break; }else{ System.out.println(name+",尝试登陆!"); out.println(name+",该用户名不存在!"); } } s.close(); } catch (Exception e) { throw new RuntimeException(ip+"校验失败!"); } } } public class LoginServer { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(4013); while(true){ Socket s = ss.accept(); new Thread(new UserThread(s)).start(); } } }
定义客户端:
package cn.itheima.day07; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; /** * 客户端通过键盘录入用户名 * 服务器端对这个用户名进行校验。 * 如果该用户名存在,在服务器端显示xxxx,已登录。 * 并在客户端显示xxx,欢迎光临。 * 如果该用户不存在,在服务器端显示xxxx,尝试登陆。 * 并在客户端显示xxxx,该用户不存在。 * 最多登陆3次,3次后结束。 * @author wl-pc */ public class LoginClient { public static void main(String[] args) throws UnknownHostException, IOException { Socket s = new Socket("127.0.0.1",4013); //用于接收客户端的输入的信息 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out =new PrintWriter(s.getOutputStream(),true); //反馈服务器端发来的反馈信息 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); for(int i=0;i<3;i++){ String line = bufr.readLine(); if(line==null) break; out.println(line); String info = bufIn.readLine(); System.out.println("info:"+info); if(info.contains("欢迎")) //包含欢迎字符,就停止 break; } bufr.close(); s.close(); } }
例子11. 客服端用本机上的浏览器,而服务端是自己定义的。
package cn.itheima.day07; import java.io.IOException; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; /** * 演示:客户端和服务端 * 1.客服端浏览器 * 服务端自定义 * @author wl-pc */ public class ServerDemo { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(4016); Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+".....connected"); PrintWriter out = new PrintWriter(s.getOutputStream(),true); out.println("客户端你好!"); s.close(); ss.close(); } }
例子12.自定义IE浏览器。
package cn.itheima.day07; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; public class MyIE { public static void main(String[] args) throws UnknownHostException, IOException { Socket s = new Socket("127.0.0.1",8080); PrintWriter out = new PrintWriter(s.getOutputStream(),true); out.println("GET /myweb/demo.html HTTP/1.1"); out.println("Accept: */*"); out.println("Accept-Language: zh-CN"); out.println("Host: 127.0.0.1:4016"); out.println("Connection: Keep-Alive"); out.println(); out.println(); BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null; while((line = bufr.readLine())!=null){ System.out.println(line); } s.close(); } }
例子13.URL链接对象
package cn.itheima.day07; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; public class URLConnetctionDemo { public static void main(String[] args) throws IOException { URL url = new URL("http://127.0.0.1:8080/myweb/demo.html"); URLConnection conn = url.openConnection();//打开连接。其实内部封装就是Socket System.out.println(conn); InputStream in = conn.getInputStream();//其实使用就是Socket类中的getInputStream byte[] buf = new byte[1024]; int len = in.read(buf); System.out.println(new String(buf,0,len)); } }
例子14.自定义GUI的IE浏览器。
import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; class MyWindow { private Frame f; private TextField tf; private Button but; private TextArea ta; MyWindow() { init(); } public void init() { f = new Frame("my window"); f.setSize(500,500); f.setLocation(400,100); f.setLayout(new FlowLayout()); tf = new TextField(40); but = new Button("转 到"); ta = new TextArea(25,60); f.add(tf); f.add(but); f.add(ta); myEvent(); f.setVisible(true); } private void myEvent() { tf.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { if(e.getKeyCode()==KeyEvent.VK_ENTER) showWeb(); } }); but.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { showWeb(); } }); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } private void showWeb() { String str_url = tf.getText(); try { //URI要比URL的范围大 URL url = new URL(str_url); URLConnection conn = url.openConnection();//打开连接。其实内部封装就是Socket //System.out.println(conn); ta.setText(""); InputStream in = conn.getInputStream();//其实使用就是Socket类中的getInputStream byte[] buf = new byte[1024]; int len = in.read(buf); ta.append(new String(buf,0,len)); /* String host = url.getHost(); int port = url.getPort(); String path = url.getPath(); Socket s = new Socket(host,port); PrintWriter out = new PrintWriter(s.getOutputStream(),true); out.println("GET "+path+" HTTP/1.1"); out.println("Accept: *"); out.println("Host: 192.168.54.9:8080"); out.println("Connection: close"); out.println(); ta.setText(""); BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null; while((line=bufIn.readLine())!=null) { ta.append(line+"\r\n"); } s.close(); */ } catch (Exception e) { e.printStackTrace(); } } } class MyIEByGUI { public static void main(String[] args) { new MyWindow(); } } //http://192.168.54.9:8080/myweb/1.html
相关文章推荐
- Java基础之网络编程知识点总结
- java基础编程学习过程中的知识点 -- 个人总结
- 黑马程序员:Java基础总结----网络编程
- 【Java基础总结】网络编程
- Java基础学习总结(18)——网络编程
- JAVA知识点总结-18 网络编程
- java基础学习总结——网络编程
- 黑马程序员 知识点总结-Java网络编程
- java基础总结25-java网络编程
- Java基础学习总结(18)——网络编程
- 黑马程序员--Java基础总结---网络编程
- 黑马程序员_Java基础:网络编程总结
- 【学习日记】java网络编程知识点总结
- 黑马程序员_Java基础:网络编程总结
- java基础学习总结——网络编程
- 【学习日记】java网络编程知识点总结
- Java基础学习总结(18)——网络编程
- 黑马程序员:Java基础总结----网络编程