网络编程要考虑模型和通讯要素:
网络模型有:
(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,通过引擎对符合规则的子串进行操作,比如取出。
----------android培训、java培训、java学习型技术博客、期待与您交流! ----------
详细请查看:http://edu.csdn.net/heima