黑马程序员——java基础——网络编程
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
几个基本概念
网络通信三要素:IP地址,端口号,传输协议
IP地址:
它是网络中的设备标识,java中对应的是InetAddress类,存在于java.net包中。
端口号:
a、用于标识进程的逻辑地址,不用进程的标识。
b、有效端口:0 ~65535,系统使用或保留的端口是:0~ 1024。
传输协议:
即通信规则,包含TCP和UDP协议
Socket
套接字,通信的端点。
就是为网络服务提供的一种机制,通信的两端都有Socket,网络通信其实就是Socket间的通信,数据在两个Socket间通过IO传输。
示例:
public class NetDemo { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub Socket s = new Socket("www.baidu.com", 8080); BufferedReader br = new BufferedReader(new InputStreamReader( s.getInputStream())); String line; while ((line = br.readLine()) != null) { System.out.println(line); } } }
TCP传输
两个端点的建立连接后会有一个传输数据的通道,这通道称为流,而且是建立在网络基础上的流,称之为socket流。该流中既有读取,也有写入。
tcp的两个端点:
一个是客户端,一个是服务端。
客户端:对应的对象,Socket
服务端:对应的对象,ServerSocket
TCP客户端:
1,建立tcp的socket服务,最好明确具体的地址和端口。这个对象在创建时,就已经可以对指定ip和端口进行连接(三次握手)。
2,如果连接成功,就意味着通道建立了,socket流就已经产生了。只要获取到socket流中的读取流和写入流即可,只要通过getInputStream和getOutputStream就可以获取两个流对象。
3,关闭资源。
TCP服务端:
1,创建服务端socket服务,并监听一个端口。
2,服务端为了给客户端提供服务,获取客户端的内容,可以通过accept方法获取连接过来的客户端对象。
3,可以通过获取到的socket对象中的socket流和具体的客户端进行通讯。
4,如果通讯结束,关闭资源。注意:要先关客户端,再关服务端。
tcp客户端
public class TcpClient { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub Socket s; s = new Socket("127.0.0.1", 1000); OutputStream os = s.getOutputStream(); os.write("你好".getBytes()); InputStream is = s.getInputStream(); byte[] buff = new byte[1024]; int len; len = is.read(buff); System.out.println(new String(buff, 0, len)); s.close(); } }
tcp服务端
public class TcpServer { public static void main(String[] args) throws Exception { ServerSocket ss = new ServerSocket(1000); Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + "is connected"); InputStream is = s.getInputStream(); byte[] buff = new byte[1024]; int len = is.read(buff); System.out.println(new String(buff, 0, len)); OutputStream os = s.getOutputStream(); os.write("已收到".getBytes()); s.close(); ss.close(); } }
模拟客户端登录
客户端通过键盘录入用户名。
服务端对这个用户名进行校验。
如果该用户存在,在服务端显示xxx,已登陆。
并在客户端显示 xxx,欢迎光临。
如果该用户不存在,在服务端显示xxx,尝试登陆。
并在客户端显示 xxx,该用户不存在。
最多就登录三次。
public class LoginClient { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub // 定义Socket Socket s = new Socket("192.168.1.102", 10008); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); PrintWriter pw = new PrintWriter(s.getOutputStream()); BufferedReader br2 = new BufferedReader(new InputStreamReader( s.getInputStream())); for (int i = 0; i < 3; i++) { String line = br.readLine(); if (line == null) { break; } pw.print(line); String line2 = br2.readLine(); System.out.println(line2); if (line2.contains("欢迎")) { break; } } br.close(); pw.close(); br2.close(); s.close(); } } public class LoginServer { public static void main(String[] args) { // TODO Auto-generated method stub try { ServerSocket ss = new ServerSocket(10008); while (true) { System.out.println("等待。。。"); Socket s = ss.accept(); System.out.println("接收"); new Thread(new UserThread(s)).start(); } } catch (Exception e) { e.printStackTrace(); } } } class UserThread implements Runnable { Socket s; UserThread(Socket s) { this.s = s; } @Override public void run() { String ip = s.getInetAddress().getHostAddress(); try { System.out.println("ip为:" + ip + "is conn"); for (int i = 0; i < 3; i++) { BufferedReader br = new BufferedReader(new InputStreamReader( s.getInputStream())); String name; if ((name = br.readLine()) == null) { break; } BufferedReader br2 = new BufferedReader(new FileReader( "user.txt")); String line; boolean flag = false; while ((line = br2.readLine()) != null) { if (line.equals(name)) { flag = true; break; } } PrintWriter pw = new PrintWriter(s.getOutputStream()); if (flag) { pw.println(name + ",欢迎光临"); break; } else { pw.println(name + ",用户名不存在"); } } s.close(); } catch (Exception e) { throw new RuntimeException(ip + "校验失败"); } } }客户端和服务的浏览器演示
浏览器是一个标准的客户端,它可以对服务端传送过来的数据消息进行解析,把符合应用层协议的消息部分解析后,将头信息拆包掉,传送到应用层,只保留了正确的正文主题部分显示在主体部分上。
而由于使用java编译是在传输层和网际层处理的,所以,会接受到全部的消息,包含了头消息。而浏览器处于应用层,已将发送来的头消息去除,只留下了主体信息。
/* * 在浏览器输入:http://localhost:11000/ * 即可访问,返回"客户端你好" */ public class ServerDemo { public static void main(String[] args) throws Exception { ServerSocket ss = new ServerSocket(11000); System.out.println("等待接收..."); Socket s = ss.accept(); System.out.println("成功"); System.out.println(s.getInetAddress().getHostAddress()); InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); System.out.println(new String(buf, 0, len)); // 返回信息写入客户端输出流 PrintWriter out = new PrintWriter(s.getOutputStream(), true);// true一定要写 out.println("<font color='red' size='7'>客户端你好</font>"); s.close(); ss.close(); } }URL和URLConnection
1、URL:
URI:范围更大,条形码也包含于此范围
URL:范围较小,即域名
方法:
1)构造函数:URL(String protocol,String host,int port,String file);//根据指定 protocol、host、port号和 file 创建 URL对象。
2)String getProtocol();//获取协议名称
3)String getHost();//获取主机名
4)int getPort();//获取端口号
5)String getFile();//获取URL文件名
6)String getPath();//获取此URL的路径部分
7)String getQuery();//获取此URL的查询部,客户端传输的特定信息
注:一般输入网址,是不带端口号的,此时可进行获取,通过获取网址返回的port,若port为-1,则分配一个默认的80端口,如
int port = getPort();
if(port == -1)
port = 80;
2、URLConnection
方法:
1)URLConnection openConnection();//用URL调用此方法,返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。
2)InputStream getInputStream();//获取输入流
3)OutputStream getOutputStream();//获取输出流
示例
public class URLConnectionDemo { public static void main(String[] args) { // TODO Auto-generated method stub /*try { URL url = new URL("http://www.baidu.com"); URLConnection conn = url.openConnection(); InputStream is =conn.getInputStream(); byte[] buff = new byte[1024]; int len; len = is.read(buff); System.out.println(new String(buff, 0, len)); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ URL url; try { url = new URL("http://192.168.1.254/myweb/demo.html?name=haha&age=30"); System.out.println("getProtocol() :"+url.getProtocol()); System.out.println("getHost() :"+url.getHost()); System.out.println("getPort() :"+url.getPort()); System.out.println("getPath() :"+url.getPath()); System.out.println("getFile() :"+url.getFile()); System.out.println("getQuery() :"+url.getQuery()); /*int port = getPort(); if(port==-1) port = 80; getPort()==-1 */ } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /* * getProtocol() :http getHost() :192.168.1.254 getPort() :-1 getPath() :/myweb/demo.html getFile() :/myweb/demo.html?name=haha&age=30 getQuery() :name=haha&age=30 */
原文地址:http://blog.csdn.net/wk843620202/article/details/45269717