Java基础之网络编程知识点总结


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



  • 8
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值