端口
网络编程
- 网络模型
OSI参考模型
TCP/IP参考模型
- 网络通讯要素
IP地址
端口号
传送协议
IP地址
获取本机InetAddress
InetAddress id = InetAddress.getLocalHost();
System.out.println("InetAddress:"+id);//获取网络地址
System.out.println("address:"+id.getHostAddress());//获取地址
System.out.println("name:"+id.getHostName());//获取主机名
根据主机名查找地址
InetAddress id = null;
try {
id = InetAddress.getByName("www.baidu.com");
} catch (UnknownHostException e) {
e.printStackTrace();
}
System.out.println(id.getHostName());
2.TCP和UDP的区别:
UDP:
1)将数据及源和目的封装成数据包,不需要建立连接。
2)每个数据报的大小限制在64k内。
3)因无连接,是不可靠协议。
4)不需要建立连接,速度快。
TCP:
1)建立连接,形成传输数据的通道。
2)在连接中进行大数据量传输。
3)通过三次握手完成连接,是可靠协议。
4)必须建立连接,效率会稍低。
Socket
为网络服务提供的一种机制,
通信的两端都是Socket
网络通信其实就是Socket间的通信
数据在两个Socket间通过IO传输
UDP的Socket服务怎么建立
DatagramSocket类表示用来发送和接收数据报包的套接字(socket)
receive(Datagram Packet p)从此套接字接收数据报包。
send(Datagram Packet p)从此套接字发送数据报包。
UDP传输
DatagramSocket和DatagramPacket
建立发送端,接受端
建立数据包
调用Socket的发送接受方法
关闭Socket
UDP发送客户端
//1.建立DatagramSocket对象
DatagramSocket ds = new DatagramSocket();
//2.将数据装入数组,并通过DatagramPacket封装成数据包
byte [] data ="Socket".getBytes();
DatagramPacket dp = new DatagramPacket(data,6,InetAddress.getByName("127.0.0.1"),20000);
//将数据包通过Socket方法发送出去
ds.send(dp);
//关闭资源
ds.close();
UDP接收端
//1.创建Socket。监听20000端口
DatagramSocket ds = new DatagramSocket(20000);
//2.建立数据包,用于存储接收到的数据
byte [] data =new byte[1024];
DatagramPacket dp = new DatagramPacket(data,1024);
//3.将收到的数据存入数据包中
ds.receive(dp);
//4.将接收到的数据打印纸显示器中:数据包现在有:地址,端口和数据
String da = new String(dp.getData(),0,dp.getLength());
InetAddress ad = dp.getAddress();
int port = dp.getPort();
System.out.println(da+""+ ad +" "+ port);
//关闭资源
ds.close();
}
tcp传输
1 tcp分客户端和服务端
2 客户端对应的对象时Socket,该对象建立时,就可以去连接指定主机
因为TCP是面向连接的,所以在建立socket服务时,就要有服务端存在,并连接成功
形成通路后在该通道进行数据传输
3 服务端对应的是ServerSocket。
tcp传输步骤:
客户端
1 创建socket服务,并指定要连接的主机和端口
2 通过客户端对象的getOutputStream方法获取输出流
3 通过获取的输出流写入数据
4 关闭socket服务
public class SocketTest {
public static void main(String[] args) throws IOException {
//创建客户端Socket对象,并指定主机和端口
Socket s = new Socket("192.168.1.100",11111);
//通过客户端对象的getOutputStream方法获取输出流
OutputStream os = s.getOutputStream();
//写入数据
os.write("aaaa".getBytes());
//关闭客户端对象
s.close();
}
}
服务端
1 建立服务端的socket服务,ServerSocket()并监听一个端口
2 获取连接过来的客户端对象:通过ServerSocket的accept方法。没有连接就会等
所以这个方法是阻塞式的
3 客户端如果发过来数据,那么服务器端要使用对应的客户端对象,并收取到该客户端
对象的读取流来读取发过来的数据
4 关闭服务器(可选)
public class ServerSocketTest {
public static void main(String[] args) throws IOException {
//创建ServerSocket对象,并监听端口
ServerSocket ss = new ServerSocket(11111);
//通过accpet方法获取连接过来的客户端对象
Socket s =ss.accept();
//通过得到的客户端对象获取输入流
InputStream in = s.getInputStream();
//创建数组,存储得到数据
byte[] buf = new byte[1024];
//通过输入流对象把数据读取到数组中
int line=in.read(buf);
System.out.println(new String(buf,0,line));
}
}
使用键盘录入,因为其有阻塞式方法,要注意回车符结束标记。当然也可用printStream 设置参数为true 自动刷新
shutdownOutput() 关闭输出流,相当于给流中加一个结束标记-1
url 类
String getFile(); 获取url的文件名
String getHost(); 获取url的主机名
String getPath(); 获取url的路径部分
String getPort(); 获取url的端口号
String getProtocol(); 获取url的协议名称
String getQuery(); 获取url的查询部
正则表达式
正则表达式:符合一定规则的表达式。
作用:用于专门操作字符串。
特点:用一些特定的符合来表达一些代码操作,这样就简化了书写
好处:可以简化对字符串的复杂操作
这种方式,使用了String类中的方法,进行组合完成了需求,但是代码过于复杂
//对QQ号进行校验,要求:5-15,0不能开头,只能是数字
public static void checkQQ(){
String qq = "112241";
if(qq.length()>5 && qq.length()<15){
if(!qq.startsWith("0")){
try{
long l = Long.parseLong(qq);
System.out.println(l);
}catch(NumberFormatException e){
System.out.println(" 只能是数字");
}
}
else{
System.out.println("不能以0开头");
}
}
else{
System.out.println("长度错误");
}
}
方法二
public static void check1QQ(){
String qq = "12141";
String regex = "[1-9][0-9]{4,14}";
//"[1-9][0-9]{4,14}"意思也就是第一位为1-9,第二位为0-9,后面出现4-14次
boolean flag = qq.matches(regex);
if(flag){
System.out.println(qq+"...ok");
}
else
System.out.println(qq+"...false");
}
具体操作功能:
匹配:用的String类中的matches()
//电话号码130和138号段的
String tel = "13000000000";
String reg = "13[0,8]\\d{8}";
System.out.println(tel.matches(reg));
切割:用的String类中的split()
String str = "ga\\g\\WHWH";
String regex = "\\\\";
String[] arr = str.split(regex);
for(String s : arr){
System.out.println(s);
按照叠词进行切割:(.)\\1+ .代表任意字符,装于()中表示组。1代表调用第1组。+出现一次或多次
替换:用的String类中的replaceAll()
//将字符串中的数组进行替换
String str = "aed613561hgd123aa";
String reg = "\\d{5,}";
String newStr = "#";
String std = str.replaceAll(reg, newStr);
System.out.println(std);
获取:将字符串中的符合规则的字符串取出
操作步骤:
1. 将正则表达式封装成对象
2. 让正则对象和要操作的字符串相关联
3. 关联后,获取正则匹配引擎
4. 通过引擎对符合规则的子串进行操作,比如取出
类Pattern
public static void getDemo(){
//单词边界\b
String str = "abga aGGH aah af ghSG AHA abaa abhah";
String reg = "\\b[a-z]{3,}\\b";
//将规则封装成对象
Pattern p = Pattern.compile(reg);
//让正则对象和要操作的字符串相关联
Matcher m = p.matcher(str);
//关联后,获取正则匹配引擎
while(m.find()){
//将规则作用到字符串上,并进行符合规则的子串查找
System.out.println(m.group());
System.out.println (m.start()+"..."+m.end());
}