Java基础--网络编程java.net

网络编程 java.net

1. 找到对方IP
2. 数据要发送到对方指定的应用程序上,为了标示这些应用程序,给这些应用程序都用数字进行标识,为了方便称呼这个数字叫做端口.
3. 定义通讯规则.也成为协议.国际组织定义了一个通用协议:TCP/IP.

我们编程涉及带传输层和网际层.
IP地址的类:InetAddress.
端口号并未封装成对象,因为只有一个数字.
传输协议:TCP,UDP
UDP:

* 将数据及源和目的封装成数据包,不需要建立连接
* 每个数据报的大小限制在64k内
* 因无连接,是不可靠的协议
* 不需要建立连接,速度快

TCP:

* 建立连接,形成传输数据的通道
* 在连接中进行大量数据传输
* 通过三次握手完成连接,是可靠协议.第一次发过来,对方收到,然后回复,然后再确认.再发出去,就可以传输数据了.
* 必须建立连接,效率会稍低

一:网络传输
网络传输一般是先找到IP地址然后把数据发送到对方指定的应用程序上,网络应用程序都用数字进行标示,就是逻辑端口。通信规则就是协议,国际组织通信规则是TCP/IP。网络参考模型如图所示。这里写图片描述
数据传输的时候都是从应用层开始往下推进,每过一层都会被数据封包,再经过传输线路传输到对方的主机上,再从物理层往上层层递进,每过一层都会被数据拆包,最后获得数据。传输层最常见协议是TCP和UDP,网际层常见协议就是IP。应用层是http协议。
二:网络通信三要素
1, IP地址:网络设备标示,本地循环地址127.0.0.1主机名localhost,IP地址是IP使用的32位或128位无符号数字,低级协议,TCP和UDP都是基于它建立而成的。
2, 端口号:标示进程的逻辑地址,0到65535,其中0到1024系统使用或者保留端口。
3, 传输协议:常见的TCP/UDP
Java.net包就是关于网络编程的数据包。
IP地址常用InetAddress类来表示,InetAddress常用的方法:

Socket:套接字

* 是一种为网络服务提供的一种机制
* 通讯的两端都有Socket
* 网络通讯其实就是Socket之间的通讯
* 数据在两个Socket中用IO传输

UDP使用DatagramSocket,
需求:
通过udp传输服务,将一段文字数据发送出去.
思路:

1. 建立UDPSocket服务
2. 提供数据,并将数据封装到数据包
3. 通过Socket服务的发送功能,将数据包发送出去
4. 关闭资源
package netDemos;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UdpSendDemo1 {

	public static void main(String[] args) throws IOException {
		// TODO 自动生成的方法存根
		// 创建udp服务,通过DatagramSocket对象.
		DatagramSocket ds = new DatagramSocket(8888);

		// 确定数据,并封装成数据包.
		byte[] data = "udp comes".getBytes();
		
		DatagramPacket dp = new DatagramPacket(data, data.length, InetAddress.getByName("127.0.0.1"), 10003);

		// 通过socket服务将已有的数据包发送出去,通过send();
		ds.send(dp);

		// 关闭资源
//		ds.close();
	}

}

改进程序使其可以发送键盘录入:

package netDemos;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UdpSendDemo2 {

	public static void main(String[] args) throws IOException {
		// TODO 自动生成的方法存根
		
		DatagramSocket ds = new DatagramSocket();
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String line = null;
		while((line=br.readLine())!=null)
		{
			byte[] buf  = new byte[line.length()];
			buf =line.getBytes();
			DatagramPacket dp = new DatagramPacket(buf, line.length(),InetAddress.getByName("127.0.0.1"),10034);
			ds.send(dp);
		}
	}

}

  • 定义一个程序用于接受udp协议传输的数据并处理数据的.
  • 定义接收端的时候都会监听一个端口,就是给这个接收网络应用程序定义个数字标识,
  • 方便于明确哪些数据
  • 1.建立udpsocket服务
  • 2.定义一个数据包,因为要存储接受到的字节数据,因为数据包对象中有更多功能可以提取字节数据
  • 不同数据信息.
  • 3.通过socket服务的receive()将受到的数据存入已经定义好的数据包中.
  • 4.通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上.
  • 5.关闭资源.

*/

package netDemos;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UdpRecDemo1 {

	public static void main(String[] args) throws IOException {
		// TODO 自动生成的方法存根
		// 1.创建udp socket服务,建立端点
		DatagramSocket ds = new DatagramSocket(10003);

		// 2.定义数据包用于存储数据
		byte[] buf = new byte[1024];

		DatagramPacket dp = new DatagramPacket(buf, buf.length);

		// 3.通过服务的receive方法将受到的数据存入数据包中
		while (true) {
			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("received From:\t" + ip + ":" + port + "\r\n" + data);
//			ds.close();
		}
	}

}

需求
编写一个聊天程序.
有接收和发送数据的部分.需要同时运行,因此需要用到多线程技术.收和发是不一致的,因此要定义两个Run方法,要封装到不同的类中.

package netDemos;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class ChatDemo {
	public static void main(String[] args) throws IOException {
		DatagramSocket ss = new DatagramSocket();
		DatagramSocket rs = new DatagramSocket(10100);
		
		new Thread(new Send(ss)).start();
		new Thread(new Rec(rs)).start();
		
		
	}
}

/*
 * 编写一个聊天程序 同时可以接收和发送,因此需要用到多线程. 要定义两个实现runnable接口的类.
 */
class Send implements Runnable {
	private DatagramSocket ds;

	Send(DatagramSocket ds) {
		this.ds = ds;
	}

	public void run() {
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			String line = null;
			while ((line = br.readLine()) != null) {
				if ("886".equals(line))
					break;
				byte[] buf = line.getBytes();
				DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("127.0.0.1"), 10100);

				ds.send(dp);
			}
		} catch (Exception e) {
			throw new RuntimeException("发送失败!");
		}
	}
}

class Rec implements Runnable {
	private DatagramSocket ds;

	Rec(DatagramSocket ds) {
		this.ds = ds;
	}

	public void run() {
		try {
			while (true) {
				byte[] buf = new byte[1024];
				DatagramPacket dp = new DatagramPacket(buf, buf.length);
				ds.receive(dp);
				String ip = dp.getAddress().getHostAddress();
				String data = new String(dp.getData(),0,dp.getLength());
				
				System.out.println(ip+":"+data);
			}
		} catch (Exception e) {
			// TODO: handle exception
			throw new RuntimeException("发送失败!");
		}
	}
}
package netDemos;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class IPDemo {

	public static void main(String[] args) throws UnknownHostException {
		// TODO 自动生成的方法存根
		InetAddress[] ia2 = InetAddress.getAllByName("www.zhanqi.tv");
		//获取服务器ip,由于网站服务器不止一个,因此ip有多个,那么InetAddress对象也有多个.用InetAddress数组接收.
		for(InetAddress is: ia2)
		{
			System.out.println(is.getHostAddress()+"\t"+is.getHostName());
		}
	}

}

Socket和ServerSocket
建立客户端和服务器端
建立连接后,通过Socket中的IO流进行数据的传输
关闭Socket
同样,客户端与服务器端是两个独立的应用.

演示Tcp传输:
Tcp分客户端和服务端.
客户端对应Socket,服务端对应ServerSocket.
客户端:通过查阅Socket对象发现该对象建立的时候就可以去连接指定的主机.因为tcp是面向连接的所以在建立Socket服务时就要有服务端存在并连接成功,形成通路后在该通道进行数据传输.
步骤:
创建客户端的Socket服务并指定要连接的主机和端口.通路一旦建立就有一个Socket流,这个流里面就有输入和输出流.getOutputStream(0;getInputStream();

package netDemos;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class TcpClientDemo1 {

	public static void main(String[] args) throws IOException {
		// TODO 自动生成的方法存根
		// 创建客户端的socket服务,指定目的主机和端口
		Socket s = new Socket("127.0.0.1", 10009);

		OutputStream os = s.getOutputStream();
		os.write("client run".getBytes());

		s.close();
	}

}
/*
 * * 1.tcp分客户端和服务端 2.服务端对应ServerSocket,客户端对应Socket
 * 
 * 通过查阅Socket发现在该对象建立的时候就应该去连接指定主机. 因为tcp是面向连接的,因此在建立socket服务时就要有服务端存在,并连接成功.
 * 形成通路后在该通道进行数据传输
 * 
 * 创建socket服务并指定要连接的主机和端口. 
 */

服务端没有流,使用客户端的流与客户端交互.

1. 服务端:定义端点接收数据并打印在控制台上
	1. 建立服务端的Socket服务-->ServerSocket();并监听一个端口.
	2. 获取连接过来的客户端对象.通过ServerSocket的accept().没有连接就会等(阻塞式方法).
	3. 客户端如果发送过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据,并打印在控制台
	4. 关闭服务端(可选择操作)
package netDemos;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpServerDemo1 {

	public static void main(String[] args) throws IOException {
		// TODO 自动生成的方法存根
		
		//建立服务端的socket服务并监听一个端口
		ServerSocket ss = new ServerSocket(10009);
		
		//通过accept方法获取连接过来的客户端对象.
		Socket s = ss.accept();
		System.out.println(s.getInetAddress().getHostAddress()+".....connected");
		//获取客户端发送过来的数据,那么要使用客户端的读取流来读取数据.
		BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
		
		String line = null;
		while((line = br.readLine())!=null)
			System.out.println(line);
		s.close();
	}

}
/*
 * *
 * 定义端点接收数据并打印到控制台上.
 * 服务端:
 * 1.建立服务端Socket服务,ServerSocket,并绑定端口.
 * 2.获取连接的客户端对象.通过ss的accept();来完成.因此这个方法是阻塞式方法.
 * 3.客户端如果发送过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流
 * 来读取发送过来的数据,打印在控制台
 * 
 */

演示Tcp的传输的客户端和服务端的互访:需求:客户端给服务端发送数据,服务端收到后给客户端反馈信息.

客户端:
建立Socket服务,指定要连接的主机和端口
获取Socket中的输出流将数据写到该流中通过网络发送给服务端.
获取Socket流中的输入流.将服务端反馈的数据获取到,并打印
关闭客户端资源
需求:建立一个文本转换服务器,客户端给服务端发送文本,服务端将文本转换成大写换回个以客户端,而且客户端可以不断进行文本转换,当客户端输入over时结束.

分析:

客户端:既然是操作设备上的数据,那么就可以使用io技术,并按照IO操作的规律来死开.
源:键盘录入.
目的:网络输出流.而且操作的是文本数据.
BufferedWriter bufw = new BufferedWriter(new )
步骤:

1. 建立服务
2. 获取键盘录入
3. 将数据发给服务端
4. 获取服务端返回的大写数据,
5. 3,4重复
6. 结束,关闭资源

都是文本数据,可以使用字符流进行操作,同时提高效率,使用Buffered流.
BufferedReader bufr = new BufferedReader(InputStreamReader(System.in));//定义读取键盘数据的流对象
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));//定义目的,将数据写入到socket输出流,发送给服务端

package netDemos;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

public class TcpClientDemo3 {

	public static void main(String[] args) throws Exception {
		// TODO 自动生成的方法存根
		Socket s = new Socket("127.0.0.1",10001);
		//定义读取键盘数据的流对象
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		//定义目的,将数据写入到socket输出流,发送给服务端
		BufferedWriter bwOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		//PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		//然后使用out的println()方法直接输出.
		//定义一个socke读取流,读取服务端返回的大写信息
		BufferedReader brIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
		
		String line = null;
		
		while((line = br.readLine())!=null){
			bwOut.write(line);
			bwOut.newLine();
			// System.out.println(line);
			bwOut.flush();
			if("over".equals(line))
				break;
			Thread.sleep(1000);
			String inline = brIn.readLine();
			System.out.println("Server:"+inline);
		}
		br.close();
	}
	

}

服务端:
源:Socket读取流
目的:Socket输出流.都是文本.

package netDemos;

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;

public class TcpServerDemo3 {

	public static void main(String[] args) throws IOException {
		// TODO 自动生成的方法存根
		ServerSocket ss = new ServerSocket(10001);
		Socket s = ss.accept();
		//读取socket读取流中的数据
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip+".....connected");
		BufferedReader brIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
		//目的:socket输出流将大写数据写入到socket的输出流中.并发送给客户端
		BufferedWriter bwOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		
//		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		//使用out.println()直接输出.
		String line = null;
		while((line = brIn.readLine())!=null){
			bwOut.write(line.toUpperCase());
			bwOut.newLine();
			bwOut.flush();
			// System.out.println(line);
		}
		s.close();
		ss.close();
	}

}
/*
 * *
 * 需求:建立一个文本服务器,处理客户端发送的字符串.服务端可以一直发送,当发送over时转换结束.
 * 
 * 分析:
 * 客户端:既然是操作数据,那么就可以使用IO技术并按照IO的操作规律来思考!
 * 源:键盘录入
 * 目的:网络输出流,网络输出流
 * 而且操作的是文本数据.字符流.
 * 
 * 步骤:
 * 1.建立服务
 * 2.获取键盘录入
 * 3.将数据发给服务端
 * 4.获取服务端返回的大写数据.
 * 5.结束,关资源.
 * 
 * 都是文本数据,可以使用字符流进行操作.同时提高效率,使用Buffered.
 * 
 * 
 * 服务端:
 * 源:socket读取流
 * 目的:socket输出流
 * 
 * 
 * 这个例题出现的问题:
 * 现象:
 * 客户端和服务端都在莫名等待,readLine()方法读取回车才可以读取得到,
 * 解决方案:因此在发送给对方数据时应该newLine()然后再flush();
 * 
 */

该例出现的问题:
现象:客户端和服务端都在莫名地等待,这就是客户端和服务端都有阻塞式的方法造成的后果.这些方法没有读到结束标记就会一直等,而导致两端都在等待.
开发时,应该查询阻塞式方法readLine().如果没有newLine()则一直等待.
上例中的流可以被PrintWriter替代:

**需求:Tcp复制文件**
分析步骤:
Tcp复制文件:

	1. 建立客户端对象,并绑定目标地址和端口.
	2. 创建一个BufferedReader读取文件FileReader
	3. PrintWriter(s.getOutputStream,true);
	4.  发送数据,使用readLine();
	5. 服务端:建立服务端对象,创建BufferedReader,PrintWriter(new FileWriter())
	6. 使用readLine(),写入到目标文件.
	7. 使用PrintWriter返回给客户端信息
	8. 关闭资源.

那么文件发送到什么时候才结束呢?我们可以在Socket类里面找一个方法.
shutdownOutput()
shutdownInput()

**服务端实现代码:**

package netDemos;

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 TcpServerDemo4 {

public static void main(String[] args) throws IOException {
	// TODO 自动生成的方法存根
	ServerSocket ss = new ServerSocket(10081);
	// 读取socket读取流中的数据
	Socket s = ss.accept();
	String ip = s.getInetAddress().getHostAddress();
	System.out.println(ip + ".....connnected");
	BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));

	PrintWriter out = new PrintWriter(new FileWriter("server.txt"), true);

	String line = null;
	String mark = br.readLine();
	while ((line = br.readLine()) != null) {
		if (mark.equals(line))
			break;
		out.println(line);
	}
	PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
	pw.println("Upload Success");

	out.close();
	s.close();
	ss.close();
	}
}

	客户端:
	
	1. 客户端点的建立
	2. 建立一个流,读取数据
	3. 发送给服务端
	4. 接受服务端的反馈信息
	5. 关闭



客户端实现代码

```package netDemos;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class TcpClientDemo4 {

	public static void main(String[] args) throws IOException {
		// TODO 自动生成的方法存根
		Socket s = new Socket("127.0.0.1", 10081);

		BufferedReader br = new BufferedReader(new FileReader("IO"));

		PrintWriter out = new PrintWriter(s.getOutputStream(), true);

		String line = null;
		// 或者也可以使用DataOutputStream发送标记,服务端也使用对应的输入流接收标记.
		// long time = System.currentTimeMillis();
		// 定义标记麻烦,可以使用Socket中的方法.
		// out.println(time);
		while ((line = br.readLine()) != null) {
			out.println(line);
		}
		// out.println(time);
		s.shutdownOutput();// 关闭客户端输出流,相当于给流中加一个-1标记.
		BufferedReader brIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

		String linein = brIn.readLine();
		System.out.println(linein);

		br.close();

		s.close();
	}

}

需求:TCP练习-客户端并发上传图片:

  ServerSocket ss = new ServerSocket(10086);
	while (true) {
		Socket s = ss.accept();
		InputStream is = s.getInputStream();
	}

这个服务端有一个局限性,当A客户端连接上以后,被服务端获取到,服务端就在执行代码,直到执行完另一个客户端才可以连接成功.因为服务端还没有处理完A客户端的请求.没有循环回来执行到accept()方法,所以暂时获取不到B客户端对象.
那么为了可以让多个客户端同时并发访问服务端,那么服务端最好就是将每个客户端封装到一个单独的线程中,那样就可以同时处理多个客户端请求.
那么如何定义线程呢?
只要明确了每一个客户端要在服务端执行的代码即可!将该代码存入Run方法中 .


	package netDemos;
	
	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;
	
	public class UploadPicServerDemo {
		public static void main(String[] args) throws IOException {
			// TODO 自动生成的方法存根
			ServerSocket ss = new ServerSocket(10086);
			while (true) {
			Socket s = ss.accept();
			new Thread(new picServer(s)).start();
			}
			ss.close();
			}
		}
	class picServer implements Runnable {
		private Socket s;
		picServer(Socket s) {
		this.s = s;
		}

	public void run() {
		InputStream in;
		String ip = s.getInetAddress().getHostAddress();
		int num = 0;
		try {
			System.out.println(ip + ".....connected");
			in = s.getInputStream();
			File f = new File(ip+""+num+".jpg");
			while(f.exists())
				f = new File(ip+""+num+++".jpg");
			FileOutputStream fos = new FileOutputStream(f);

			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("Upload success".getBytes());

			fos.close();
			s.close();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			throw new RuntimeException(ip + "上传失败!");
			}
		}
	}


那么在客户端,为了服务器性能的考虑,我们应该限制客户发送过大或者其他格式的文件.

package netDemos;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class UploadPicClientDemo {

public static void main(String[] args) throws IOException {
	// TODO 自动生成的方法存根
	if (args.length != 1) {
		System.out.println("只允许一个参数");
		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*8){
		System.out.println("图片过大!");
		return;
	}
	Socket s = new Socket("127.0.0.1", 10086);

	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();
}

}
/*

    • 客户端: 1.服务端点 2.读取图片数据 3.通过socket输出流将数据发送给服务端. 4.读取服务端反馈信息 5.关闭socket.
      */


**需求:客户端通过键盘录入用户名,服务端对这个用户名进行校验.如果该用户存在那么服务端显示xxx已登录.并在客户端显示xxx欢迎光临.如果用户不存在,服务端显示xxx尝试登录.在客户端显示xxx,该用户不存在.最多登录三次.**

**客户端实现代码**

package netDemos;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class LoginClientDemo {

public static void main(String[] args) throws IOException {
	// TODO 自动生成的方法存根
	Socket s = new Socket("127.0.0.1", 10023);

	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

	PrintWriter out = new PrintWriter(s.getOutputStream(), true);

	BufferedReader brIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

	for (int x = 0; x < 3; x++) {
		String line = br.readLine();
		if(line==null)
			break;
		out.println(line);
		String info = brIn.readLine();
		if(info.contains("welcome"))
			break;
		System.out.println("info:" + info);
	}
	br.close();
	s.close();
}

}

**服务端实现代码**

package netDemos;

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;

public class LoginServerDemo {

public static void main(String[] args) throws IOException {
	// TODO 自动生成的方法存根
	ServerSocket ss = new ServerSocket(10023);

	while (true) {
		Socket s = ss.accept();

		new Thread(new UserThread(s)).start();
	}
}

}

class UserThread implements Runnable {
private Socket s;

UserThread(Socket s) {
	this.s = s;
}

public void run() {
	String ip = s.getInetAddress().getHostAddress();
	BufferedReader br = null;
	System.out.println(ip + ".....connected");

	try {
		for (int x = 0; x < 3; x++) {
			BufferedReader brIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
			String name = brIn.readLine();
			if (name == null)
				break;
			br = new BufferedReader(new FileReader("user.txt"));
			PrintWriter out = 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(name + ",已登录!");
				out.println(name + ",欢迎光临");
				break;
			} else {
				System.out.println(name + ",尝试登录!");
				out.println(name + "用户不存在!");
				break;
			}
		}
		br.close();
		s.close();
	} catch (Exception e) {
		// TODO: handle exception
		throw new RuntimeException(ip + "校验失败!");
	}
}

}


类 **URL** 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。

与IO流相同,IO流有个类叫做File,net有个类叫做URL.该类使用字符串进行操作.使用该类需要进行异常处理.
参数:
protocol - 要使用的协议名称。
host - 主机名称。
port - 主机端口号。
file - 主机上的文件 

package netDemos;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

public class URLDemo {

public static void main(String[] args) throws IOException {
	// TODO 自动生成的方法存根
	URL url = new URL("http://127.0.0.1:11000/myweb/demo.html");
	
	System.out.println(url.getProtocol());
	System.out.println(url.getHost());
	System.out.println(url.getPort());
	System.out.println(url.getPath());
	System.out.println(url.getFile());
}

}


package netDemos;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class URLConnectionDemo {

public static void main(String[] args) throws IOException {
	// TODO 自动生成的方法存根
	URL url = new URL("http://localhost:8080");
	
	URLConnection conn = url.openConnection();

// System.out.println(conn);
InputStream is = conn.getInputStream();

	byte[] buf = new byte[1024];
	int len = 0;
	while((len=is.read(buf))!=-1){
		System.out.println(new String(buf,0,len));
	}
}

}
//通过这段代码可以看出,URL这个类方便于我们进行网络编程,其实URL类内部封装了Socket类我们才得以方便地使用Socket流进.



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值