黑马程序员——java网络编程

                            ---------- android培训java培训、java学习型技术博客、期待与您交流! ----------
 

 

 网络编程要考虑模型和通讯要素:

   网络模型有:

   (1)OSI参考模型:分为7层,对数据封包,到物理层,就通过网线或无线传送给对方,对方就对数据包进行拆包

   (2)TCP/IP参考模型:分为4层

    网络通讯要素:IP地址;端口号;传输协议

    发送信息步骤:

    (1)找到对方IP(InetAddress)

    (2)数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识,为了方便称呼这个数字,叫做 端口。逻辑端口(老毕的讲的例子:IP地址是大楼地址,端口是房间号)

    (3)定义通信规则,这个通信规则称为协议。国际组织定义了通用协议 TCP/IP

    

本地回环地址为127.0.0.1,主机名:localhost

IPV4全是数字,IPV6数字与字母组合

常见协议:

UDP(DatagramSocket / DatagramPacket)

·将数据及源和目的封装成数据包,不需要建立连接

·每个数据报的大小在限制在64k

·因无连接,是不可靠协议

·不需要建立连接,速度快

例子:寄东西

如果想要接收到信息,接收端要先执行,等待发送端发送信息,否则发送端发送的数据会丢失

TCP

·建立连接,形成传输数据的通道

·在连接中进行大数据量传输

·通过三次握手完成连接,是可靠协议

·必须建立连接,效率会稍低

例子:打电话

Socket

·Socket就是为网络服务提供的一种机制

·通信的两端都有Socket

·网络通信其实就是Socket间的通信

·数据在两个Socket间通过IO传输

     TCP传输

     ·Socket和ServerSocket

     ·建立客户端和服务器端(服务端要先开启

     ·建立连接后,通过Socket中的IO流进行数据的传输

     ·关闭Socket

     

     同样,客户端与服务器端是两个独立的应用程序。

    基本思路(客户端)l

    (1)客户端需要明确服务器的ip地址以及端口,这样才可以去试着建立连接,如果连接失败,会出现异 常。

    (2)连接成功,说明客户端与服务端建立了通道,那么 通过IO流就可以进行数据的传输,而Socket对象已经提供了输入流和输出流对象,通过 getInputStream(),getOutputStream()获取即可。

l  (3)与服务端通讯结束后,关闭Socket。

    通过Socket建立对象并指定要连接的服务端主机以及端口。

    Socket s = new Socket(“192.168.1.1”,9999);

    OutputStream out = s.getOutputStream();

    out.write(“hello”.getBytes());

    s.close();

    基本思路(服务端)

    (1)服务端需要明确它要处理的数据是从哪个 端口进入的。

    (2)当有客户端访问时,要明确是哪个客户 端,可通过accept()获取已连接的客户端对象,并通过该对象与客户端通过IO流进行数据传输。

(3)当该客户端访问结束,关闭该客户端。

建立服务端需要监听一个端口

ServerSocket ss = new ServerSocket(9999);

Socket s = ss.accept ();

InputStream in = s.getInputStream();

byte[] buf = new byte[1024];

int num = in.read(buf);

String str = new String(buf,0,num);

System.out.println(s.getInetAddress().toString()+”:”+str);

s.close();

ss.close();

/*

需求:给服务端发一个文本数据

步骤

1,创建socket,并指定要连接的主机和端口

2,获取输出流,发送数据

3,接收服务端反馈信息

4,关闭客户端

*/

import java.io.*;

import java.net.*;

class Client2

{

public static void main(String[] args) throws Exception

{

Socket s = new Socket("127.0.0.1",10004);

//为了发送数据,应该获取socket中的输出流

OutputStream out = s.getOutputStream();

out.write("tcp ge men lai le ".getBytes());

//为了获得服务端反馈信息,应该获取socket中的输入流

InputStream in = s.getInputStream();

byte[] buf = new byte[1024];

int len = in.read(buf);

System.out.println(new String(buf,0,len));

s.close();

}

}

/*

需求:向客户端反馈信息

服务端:

1,建立服务端socket服务,ServerSocket

   并监听一个端口

2,获取连接过来的客户端对象

   通过accept方法完成,没有连接就会等待,所以这个方法是阻塞式的

3,客户端如果发送数据,那么服务端要使用对应的客户端对象,并

获取到该客户端对象的读取流来读取发过来的数据

4,反馈信息

5,关闭服务端(可选操作)

*/

class  TCPServer2

{

public static void main(String[] args)  throws Exception

{

//建立服务端,监听一个端口

ServerSocket ss = new ServerSocket(10004);

//通过accept方法获取连接过来的客户端对象

Socket s = ss.accept();

String ip = s.getInetAddress().getHostAddress();

System.out.println(ip+".........");

//获取客户端发送过来的数据,那么服务端要

//使用客户端读取流读取数据

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("client,i got the data you sent".getBytes());

//关闭资源

s.close();

ss.close();//只服务一次

}

}

 

Tcp传输最容易出现的问题

    (1)客户端连接上服务端,两端都在等待,没有任何数据传输。

    (2)通过例程分析:

      因为read方法或者readLine方法是阻塞式。

    (3)解决办法:

      •自定义结束标记

      •使用shutdownInput,shutdownOutput方法。

 

 

/*

需求:建立一个文本转换服务器

科幻段给服务端发送文本,服务端会将文本转成大写再返回给客户端

循环,输入over就结束

分析:

客户端:

操作设备上的数据,就可以使用io技术,并按照io的操作规律来思考

1,源:键盘

   目的:网络设备(网络输出流)

2,操作的是文本数据,选择字符流

步骤:

1,建立服务

2,获取键盘录入

3,将数据发给服务端(循环)

4,获取服务端返回的大写数据

5,结束,关资源

都是文本数据,可以使用字符流进行操作,同时提高效率

加入缓冲

*/

import java.io.*;

import java.net.*;

class  TransClient

{

public static void main(String[] args) throws Exception

{

Socket s = new Socket("127.0.0.1",10005);

//输入流,获取键盘录入

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;

//readLine方法只读取回车之前的数据

//要自己加结束标记和flush

while ((line=bufr.readLine())!=null)

{

if("over".equals(line))

break;

//发一句

bufOut.write(line);

bufOut.newLine();

bufOut.flush();//要刷新

//读一句

String str = bufIn.readLine();

System.out.println("大写是:"+str);

}

bufr.close();

s.close();//在socket标记一个-1

}

}

class  TransServer

{

public static void main(String[] args)  throws Exception

{

ServerSocket ss = new ServerSocket(10005);

Socket s = ss.accept();

String ip=s.getInetAddress().getHostAddress();

System.out.println("ip="+ip);

//源

BufferedReader bufIn = new BufferedReader(

new InputStreamReader(s.getInputStream()));

//目的

BufferedWriter bufOut = new BufferedWriter(

new OutputStreamWriter(s.getOutputStream()));

String line=null;

//readLine读到了数据,但是没结尾标记,不知道什么时候结束

//要自己加结束标记和flush

while ((line=bufIn.readLine())!=null)

{

System.out.println(line);

bufOut.write(line.toUpperCase());

bufOut.newLine();

bufOut.flush();

}

s.close();

ss.close();

}

}

/*

该例子出现的问题

现象:客户端和服务端都早莫名的等待

为什么呢?

因为客户端和服务端都有阻塞式方法,这些方法没有读到结束标记,那么就一直等

而导致两端,都在等待

*/

 

 

正则表达式:(重点)
正则表达式:符合一定规则的表达式。
作用:用于专门操作字符串。
特点:用于一些特定的符号来表示一些代码操作。这样就简化书写。


所以学习正则表达式,就是在学习一些特殊符号的使用。
好处:可以简化对字符串的复杂操作。
弊端:符号定义越多,正则越长,阅读性越差。


具体操作功能:
1,匹配:String  matches方法。用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false。
2,切割:String split();
3,替换:String replaceAll(regex,str);如果regex中有定义组,可以在第二参数中通过$符号获取正则表达式中的已有的组。
4,获取:将字符串中的符合规则的子串取出。

操作步骤:
1,将正则表达式封装成对象。
2,让正则对象和要操作的字符串相关联。
3,关联后,获取正则匹配引擎。
4,通过引擎对符合规则的子串进行操作,比如取出。

import java.util.regex.*;

class RegexTest
{
public static void main(String[] args) 
{
getDemo();
}
public static void getDemo()
{
String str = "ming tian jiu yao fang jia le ,da jia。";
System.out.println(str);
String reg = "\\b[a-z]{4}\\b";

//将规则封装成对象。
Pattern p = Pattern.compile(reg);

//让正则对象和要作用的字符串相关联。获取匹配器对象。
Matcher m  = p.matcher(str);

//System.out.println(m.matches());//其实String类中的matches方法。用的就是Pattern和Matcher对象来完成的。
//只不过被String的方法封装后,用起来较为简单。但是功能却单一。

// boolean b = m.find();//将规则作用到字符串上,并进行符合规则的子串查找。
// System.out.println(b);
// System.out.println(m.group());//用于获取匹配后结果。
//System.out.println("matches:"+m.matches());
while(m.find())
{
System.out.println(m.group());
System.out.println(m.start()+"...."+m.end());
}
}
}
 
 
个人总结
在网络编程方面,内容比较多。但是这个很重要,跟IO一样重要。总结为TCP,UDP,Socket通讯,以及结合io操作。
正则这一块,正则功能强大,简便,但是不是很容易看懂,一开始学习也不知所云,看多了几次,就习惯了,自己也习惯了用正则来验证。
最吸引人的就是网络爬虫了,可以一直抓取网页内容。

                             ----------android培训java培训、java学习型技术博客、期待与您交流! ----------


                                                         详细请查看:http://edu.csdn.net/heima

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值