java学习笔记 22-25 GUI 网络编程 正则表达式



110 GUI概述 
JAVA为GUI提供的对象都存在
于 java.Awt 与 javax.Swing


java.Awt 
abstract window toolkit
需要调用本地系统功能实现功能


javax.Swing
在AWT基础上建立了一套图形界面系统


Container:容器,是个特殊的组件,
该组件可以通过add方法添加其他组件进来






111 布局管理器
FlowLayout 流式布局 从左到右的顺序 (Panel默认)
BorderLayout 边界布局 东南西北中 (Frame默认,不写东南西北就占用所有空间)
GridLayout 网格式布局
CardLayout 选项卡
GridBagLayout 网格包布局




112 Frame
Frame(String title) 
          构造一个新的、最初不可见的、具有指定标题的 Frame 对象。
Frame 是带有标题和边框的顶层窗口




/*
创建图形化界面
1 创建Frame窗体
2 对窗体进行基础设置
比如 大小 位置 布局
3 定义组件
4 将组件通过窗体的add方法添加到add中
5 让窗体显示 通过setVisible(true)
*/




import java.awt.*;
class Demo
{
public static void main(String[] args) throws Exception
{
Frame f = new Frame("myawt");
 
f.setVisible(true);
f.setSize(500,400); //宽 高
f.setLocation(400,200); //设置位置
f.setLayout(new FlowLayout());
Button b = new Button("我是一个按钮");
f.add(b);
}
 
}


 113 事件监听


事件监听机制的特点:
1 事件源
2 事件
3 监听器
4 事件处理


事件源:awt或者swing包中的图形界面组件
事件:每个事件源都有自己特有的对应和共性事件
监听器:将可以触发某个事件的动作(不只一个)都已经封装到监听器中
以上三者 java都定义好了
直接获取其对象就可以用了
我们可以做的就是,对产生的动作进行处理


public void addWindowListener(WindowListener l)
WindowListener 是一个接口,要使用它就要覆盖它的七个方法
可是我只用其中的关闭动作,其他方法却必须重复写
class MyWin implements WindowListener
{
  windowClosing(WindowEvent e) 
          窗口正处在关闭过程中时调用。
....
}
这样写很麻烦 


WindowAdapter 继承自 WindowListener ,但七个方法都是空的
于是我们很简单 继承 WindowListener 再 覆盖需要的方法就可以了


class MyWin extends WindowAdapter
{
public windowClosing(WindowEvent e) 
    {
... 
}
}


114 窗体事件 
//


import java.awt.*; //界面包
import java.awt.event.*; //事件包


class Demo
{
public static void main(String[] args) throws Exception
{
Frame f = new Frame("myawt");
 
f.setVisible(true);
f.setSize(500,400); //宽 高
f.setLocation(400,200); //设置位置
f.setLayout(new FlowLayout());

Button b = new Button("我是一个按钮");
f.add(b);
 
f.addWindowListener(new WindowAdapter()
{
public void  windowClosing(WindowEvent e) 
{
System.out.println("我被关闭了");
System.exit(0);
}

public void windowActivated(WindowEvent e) 
{
System.out.println("我被激活了");
}

public void windowOpened(WindowEvent e) 
{
System.out.println("我被打开了");
}
 
 
}
);
}
 
}


114 Action 事件




import java.awt.*; //界面包
import java.awt.event.*; //事件包


class FrameDemo
{
private Frame f;
private Button but;


FrameDemo()
{
init();
}

public void init()
{
f = new Frame("我的窗体");
//对Frame进行基本设置
f.setBounds(300,100,500,400); //  void setBounds(int x, int y, int width, int height) 
f.setLayout(new FlowLayout());
but = new Button("按钮");
//将组件安装到frame中
f.add(but);
//加载窗体事件
myEvent();
//显示窗体
f.setVisible(true);
}

private  void myEvent()
{
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});

/*让按钮具备退出程序的功能
按钮就是事件源
那么选择哪个监听器呢?
通过关闭窗体示例了解到,
想要知道哪个组件具备什么样的特有监听器,需要查看该组件支持的功能
*/

//void addActionListener(ActionListener l) 
//ActionListener接口中只有一个函数 所以没有适配器(adapter)
but.addActionListener(new ActionListener()
{
private int count = 1;
public  void actionPerformed(ActionEvent e) 
{
/* //点一下就退出
System.out.println("点击按钮,退出");
System.exit(0);
*/

/*//点一下就增加一个按钮
f.add(new Button("Button-"+(count++)));
f.setVisible(true); //添加新控件之后要重新设置显示,才能显示出来(重新显示一次)
f.validate();    //确保组件具有有效的布局。(貌似是重新布局一次)
*/


// ActionEvent 中 public Object getSource()最初发生 Event 的对象。 
// Component 中  public Container getParent()获取此组件的父级。 
System.out.println(e.getSource());
Button b = (Button)e.getSource();
Frame f1 = (Frame)b.getParent();
f1.add(new Button("button-"+count++));
f1.validate();

}
});

}


public static void main(String[] args)  

FrameDemo f = new FrameDemo();
}
}


 
115 鼠标键盘事件
鼠标和键盘在每个组件中都有
所以在Component接口中
void addKeyListener(KeyListener l) 
          添加指定的按键侦听器,以接收发自此组件的按键事件。 
 void addMouseListener(MouseListener l) 
          添加指定的鼠标侦听器,以接收发自此组件的鼠标事件。 




import java.awt.*; //界面包
import java.awt.event.*; //事件包


class MouseDemo
{
private Frame f;
private Button but;
private TextField tf;


MouseDemo()
{
init();
}

public void init()
{
f = new Frame("我的窗体");
f.setBounds(300,100,500,400);  
f.setLayout(new FlowLayout());
but = new Button("---------按钮------------");
f.add(but);
tf = new TextField(10); //传入列数 因为它只有一行
f.add(tf);
myEvent();
f.setVisible(true);
}

private  void myEvent()
{
//frame添加窗体监听器
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});

//按钮Action监听器
but.addActionListener(new ActionListener()
{
public  void actionPerformed(ActionEvent e) 
{
System.out.println("按钮Action监听");
}
});
 
//为键盘添加鼠标监听器
but.addMouseListener(new MouseAdapter()
{
private int count = 1;
private int click_count = 1;
public  void mouseEntered(MouseEvent e) //鼠标进入到组件上时调用。 
{
System.out.println("鼠标进入按钮区域"+count++);
}

public void mouseExited(MouseEvent e)
{
System.out.println("鼠标离开按钮区域");
}
// 按钮上的鼠标点击事件发生在按钮的Action监听事件之前
//二者之间的区别是:按钮上的Action事件可以由鼠标键盘等触发
//所以监控按钮点击还是要使用Action事件
//而监控鼠标双击还是要使用MouseListener

public void mouseClicked(MouseEvent e) 
{
if(e.getClickCount() == 2) //获取与此时间关联的点击次数
{
System.out.println("鼠标双击"+click_count++);
}

//这个是写着玩 还真的可以三击
if(e.getClickCount() == 3)
{
System.out.println("3击");
}
}
}
);

//为按钮添加键盘监听器
but.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)   //按下某个键时调用此方法。 
{
System.out.println(e.getKeyChar()+" "+e.getKeyCode()+ 
" " + KeyEvent.getKeyText(e.getKeyCode()));
//KeyEvent.getKeyText(int )  返回描述 keyCode 的 String,如 "HOME"、"F1" 或 "A"。

/*
//按ESC退出
if(e.getKeyCode() == KeyEvent.VK_ESCAPE)
{
System.exit(0);
}
*/

//按CTRL+ENTER退出 (组合键)
if(e.isControlDown() && e.getKeyCode()==KeyEvent.VK_ENTER )
{
System.out.println("ctrl + enter");
System.exit(0);
}
}
});

//我想让文本条中只能输入数字
tf.addKeyListener(new KeyAdapter()
{
public  void keyPressed(KeyEvent e) 
{
char c = e.getKeyChar();
if(c >= '0' && c <= '9')
{

}
else
{
e.consume(); //使用此事件,以便不会按照默认的方式由产生此事件的源代码来处理此事件。 
}
}
});
 
}


public static void main(String[] args)  

MouseDemo f = new MouseDemo();
}
}
记住 凡是做图形化界面都是先画界面


116 练习  显示文件夹内容


import java.awt.*; //界面包
import java.awt.event.*; //事件包
import java.io.*;


class Demo
{
private Frame f;
private TextField  tf;
private Button btn;
private TextArea ta;

Demo()
{
init();
}

public void init()
{
f = new Frame("我的窗口");
f.setBounds(300,100,600,500);
f.setLayout(new FlowLayout());
tf = new TextField(70);
btn = new Button("转到");
ta = new TextArea(15,80); //行数 列数

f.add(tf);
f.add(btn);
f.add(ta);
myEvent();
f.setVisible(true);

}

private void myEvent()
{
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e) 
{
System.exit(0);
}
});

btn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e) 
{
ta.setText(""); //清空
String dirpath = tf.getText();
File dir = new File(dirpath);
if(dir.exists() && dir.isDirectory())
{
String[] names = dir.list();
for(String name : names)
{
ta.append(name+"\r\n");
}
}
else
{
ta.setText("文件夹未找到!");
}

}
}
);
}




public static void main(String[] args)
{
Demo d = new Demo();
}


}




117 对话框
Dialog 类 也是一种容器
setLayout
add 
event 
setVisible 
也是这种套路




import java.awt.*; //界面包
import java.awt.event.*; //事件包
import java.io.*;


class Demo
{
private Frame f;
private TextField  tf;
private Button btn;
private TextArea ta;


Demo()
{
init();
}

public void init()
{
f = new Frame("我的窗口");
f.setBounds(300,100,600,500);
f.setLayout(new FlowLayout());
tf = new TextField(70);
btn = new Button("转到");
ta = new TextArea(15,80); //行数 列数

myEvent();

f.add(tf);
f.add(btn);
f.add(ta);

f.setVisible(true);

}

private void myEvent()
{
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e) 
{
System.exit(0);
}
});

btn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e) 
{
showDir();
}
}
);

tf.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_ENTER)

showDir();
}
}
}
);
}




public void showDir()
{
ta.setText(""); //清空
String dirpath = tf.getText();
File dir = new File(dirpath);
if(dir.exists() && dir.isDirectory())
{
String[] names = dir.list();
for(String name : names)
{
ta.append(name+"\r\n");
}
}
else
{
showDialog();
}

}

public void showDialog()
{
final Dialog d = new Dialog(f,"提示信息",true);
//第一个参数是父Frame 第二个是标题 第三个true表示对话框存在时不能操作窗体
d.setBounds(500,200,200,100);
Label l = new Label("文件夹未找到");
Button okBtn = new Button("OK");
d.add(l,BorderLayout.NORTH);
d.add(okBtn);
d.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e) 
{
d.setVisible(false);
}
});

okBtn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e) 
{
d.setVisible(false);
}
}
);

okBtn.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_ENTER)
{
d.setVisible(false);
}
}
}
);


d.setVisible(true);
}

public static void main(String[] args)
{
Demo d = new Demo();
}


}
 






118 菜单
MenuBar 菜单栏 (窗体 setMenuBar(MenuBar) 来添加菜单栏)
Menu 菜单项 (可以add 菜单条目与菜单项)
MenuItem 菜单条目(被Menu add,可以添加addActionListener监听器)
import java.awt.*; //界面包
import java.awt.event.*; //事件包
 


class Demo
{
private Frame f;
private MenuBar mb;
private Menu m;
private MenuItem closeItem;
private Menu subItem;
private MenuItem newItem;


Demo()
{
init();
}

public void init()
{
f = new Frame("我的窗口");
f.setBounds(300,100,600,500);
f.setLayout(new FlowLayout());

mb = new MenuBar();
m = new Menu("文件");
closeItem = new MenuItem("退出");
subItem = new Menu("更多");
newItem = new MenuItem("新建");


m.add(closeItem);
subItem.add(newItem);
m.add(subItem);
mb.add(m);

f.setMenuBar(mb);
myEvent();
f.setVisible(true);
 
}

private void myEvent()
{
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e) 
{
System.exit(0);
}
});

closeItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
);

}

 

public static void main(String[] args)
{
Demo d = new Demo();
}


}


119 打开 保存文件




import java.awt.*; //界面包
import java.awt.event.*; //事件包
import java.io.*;


class Demo
{
private Frame f;
private MenuBar mb;
private Menu m;
private MenuItem openItem,saveItem,closeItem;
private TextArea ta;
private FileDialog openDialog,saveDialog; //文件对话框
private File file;


Demo()
{
init();
}

public void init()
{
f = new Frame("记事本");
f.setBounds(300,100,600,500);


mb = new MenuBar();
m = new Menu("文件");

openItem = new MenuItem("打开");
saveItem = new MenuItem("保存");
closeItem = new MenuItem("退出");


m.add(openItem);
m.add(saveItem);
m.add(closeItem);
mb.add(m);
f.setMenuBar(mb);

ta = new TextArea();
f.add(ta);

myEvent();

f.setVisible(true);
openDialog = new FileDialog(f,"我要打开",FileDialog.LOAD);
saveDialog = new FileDialog(f,"我要关闭",FileDialog.SAVE);
}

private void myEvent()
{
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e) 
{
System.exit(0);
}
});

closeItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
);

openItem.addActionListener(new ActionListener()  
{
public void actionPerformed(ActionEvent e)
{
openDialog.setVisible(true);
if(openDialog.getDirectory()!=null && openDialog.getFile()!=null) //若有一个为空 都表示获取失败 因为用户可以按取消或者点关闭
{
file = new File(openDialog.getDirectory(),openDialog.getFile());
ta.setText("");
BufferedReader br = null;
try
{
br = new BufferedReader(new FileReader(file));
String line = null;
while((line=br.readLine()) != null)
{
ta.append(line+"\r\n");
}
}
catch(IOException e1)
{
throw new RuntimeException("原始文件打开错误");
}
finally
{
try
{
if(br != null)
{
br.close();
}
}
catch(IOException e2)
{
throw new RuntimeException("原始文件关闭错误");
}
}
}
}
}
);


saveItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//保存对话框出现的条件: 1 文件改变 2文件路径不存在
BufferedWriter bw = null;

try
{
if(file == null)
{
saveDialog.setVisible(true);
if(saveDialog.getDirectory()!=null && saveDialog.getFile() !=null)
{
File savefile =  new File(saveDialog.getDirectory(),saveDialog.getFile());
bw = new BufferedWriter(new FileWriter(savefile));
}
}
else
{
bw = new BufferedWriter(new FileWriter(file));
}

saveFileTo(bw);
if(bw != null) bw.close();
}
catch(IOException ex)
{
throw new RuntimeException("保存失败");
}
}
}
);

}

 
public void saveFileTo(BufferedWriter bw) throws IOException
{

if(bw == null) return;

BufferedReader br = new BufferedReader(new StringReader(ta.getText()));
String line = null;
while((line=br.readLine()) != null)
{
bw.write(line);
bw.newLine();
}
br.close();
}


public static void main(String[] args)
{
Demo d = new Demo();
}


}


 


 


 


 
 
 
  
120 IP地址
通过 InetAddress 此类表示IP地址
直接获取本机 或者 通过IP地址字符串获得此对象


import java.net.*;
class Demo
{
public static void main(String[] args) throws Exception
{
//InetAddress 没有构造函数 只能通过静态函数获取
//获得本机的InetAddress对象
InetAddress i = InetAddress.getLocalHost();
sop(i.toString()); //XP-201307041609/192.168.22.1
//分别打印 IP地址
sop(i.getHostAddress()); //获得IP地址
sop(i.getHostName()); //获得主机名称

//通过IP地址获得InetAddress对象 (最方便)
InetAddress ia  = InetAddress.getByName("www.baidu.com");
sop(ia.getHostAddress()); //获得IP地址
sop(ia.getHostName()); //获得主机名称



}
 
 
public static void  sop(Object obj)
{
System.out.println(obj);
}
}




121 UDP
DatagramSocket: 此类表示用来发送和接收数据报包的套接字。 总是通过UDP传送
发送时用
DatagramSocket() 
          构造数据报套接字并将其绑定到本地主机上任何可用的端口。 
接收时用  
DatagramSocket(int port) 
          创建数据报套接字并将其绑定到本地主机上的指定端口。 








DatagramPacket: 此类表示数据报包。 
 既用来接收 也用来发送 构造函数中 带地址的 都是用来发送数据包的 
 
 
用于接收:
DatagramPacket(byte[] buf, int length) 
          构造 DatagramPacket,用来接收长度为 length 的数据包。 
DatagramPacket(byte[] buf, int offset, int length) 
 构造 DatagramPacket,用来接收长度为 length 的包,在缓冲区中指定了偏移量。 
 
用于发送:
DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
          构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。 
DatagramPacket(byte[] buf, int length, SocketAddress address) 
          构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
 
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) 
          构造数据报包,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。 
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) 
          构造数据报包,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。 
 
发送端:


 import java.net.*;
class UdpSend
{
public static void main(String[] args) throws Exception
{
//1 创建UDP服务 通过DataGramSocket对象
DatagramSocket ds = new DatagramSocket(8888); 
//这里其实也能绑定个端口,指定发送端口 如果不指定则用随机端口

//2 确定数据包内容
//DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
byte[] data = "hello,udp".getBytes();
DatagramPacket dp = new DatagramPacket(data,data.length,
InetAddress.getByName("125.221.182.196"),10000);

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

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



}
 
 
public static void  sop(Object obj)
{
System.out.println(obj);
}
}


 
UDP接收端:
//定义一个应用程序 用于接收和处理数据
/*
1 定义socket套接字 DatagramSocket,通常要
2 定义接收数据的DatagramPacket对象
3 通过socket服务的receive方法接收数据 存储在定义好的DatagramPacket对象中
4 通过数据包对象特有功能,将数据包中内容取出来
5 关闭资源


*/
import java.net.*;
class UdpRec
{
public static void main(String[] args) throws Exception
{
//1 创建udp socket服务,建立端点
DatagramSocket ds = new DatagramSocket(10000);
//2 定义数据包
byte[] buf = new byte[1024];
while(true)
{
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//3 通过服务的recevie方法将数据存储在数据包中
ds.receive(dp);
//4 通过数据包对象的方法提取内容
byte[] data = dp.getData();
String ip = dp.getAddress().getHostAddress(); //发送端使用的ip
int port = dp.getPort(); //发送端使用的端口
System.out.println(ip+":"+port+"--"+new String(data,0,dp.getLength()));

}


// ds.close();
}
}


122 从键盘输入 发送UDP
 
 import java.net.*;
 import java.io.*;
class UdpSend
{
public static void main(String[] args) throws Exception
{
 
DatagramSocket ds = new DatagramSocket(8888); 
 
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,0,
InetAddress.getByName("125.221.182.196"),10000);
while((line=bufr.readLine()) != null)
{
if("886".equals(line)) break;
buf = line.getBytes();
dp.setData(buf);
dp.setLength(buf.length); 
ds.send(dp);
}

ds.close();
}
 
public static void  sop(Object obj)
{
System.out.println(obj);
}
}


接收端还是使用前面那个




123 聊天程序
import java.net.*;
import java.io.*;
 
class UdpChat1
{
public static void main(String[] args) throws Exception
{
 
DatagramSocket sendSocket = new DatagramSocket(); 
BufferedReader sendBufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
byte[] sendBuf = new byte[1024];
 
Thread t = new Rec1();
t.setDaemon(true); //将接收线程设置为守护线程,当所有的线程是守护线程时,虚拟机退出.
t.start();


DatagramPacket dp = new DatagramPacket(sendBuf,0,
InetAddress.getByName("125.221.182.196"),20000);  
while((line=sendBufr.readLine()) != null)
{
if("886".equals(line)) 
{
break;
}
sendBuf = line.getBytes();
dp.setData(sendBuf);
dp.setLength(sendBuf.length); 
sendSocket.send(dp);
}

sendSocket.close();
}
 
public static void  sop(Object obj)
{
System.out.println(obj);
}
}




class Rec1 extends Thread
{
public void run()
{
byte[] buf = new byte[1024];
DatagramSocket recSocket = null;
try
{
recSocket = new DatagramSocket(10000);  
DatagramPacket recPack = new DatagramPacket(buf,buf.length);
while(true)
{
recSocket.receive(recPack);
String ip = recPack.getAddress().getHostAddress();
String msg = new String(recPack.getData(),0,recPack.getLength());
int port = recPack.getPort();
System.out.println(ip+":"+port+"-->"+msg);
}
}
catch(Exception e)
{
throw new RuntimeException("接收错误");
}
finally
{
recSocket.close();
}
}
}
 
124 TCP传输
Socket 客户端
ServerSocket 服务端 


/*
Tcp演示
1 tcp分客户端和服务端
2 客户端Socket 
  服务端ServerSocket


  客户端:
  通过查阅Socket对象,发现该对象建立时,就可以去连接指定主机
  因为tcp是面向连接的,所以在建立socket服务时,就要有服务器存在,并连接成功.
  形成同路后,在该通道进行数据的传输
  
  
  需求:
  定义客户端连接服务器,并发送数据
  
   步骤:
   1 创建Socket服务,并指定要连接的主机和端口
   Socket(String host, int port) 
          创建一个流套接字并将其连接到指定主机上的指定端口号
2 获取自己的输出流对象,将要发送数据写入
   3 关闭Socket服务
*/ 
 
import java.net.*;
import java.io.*;
 
class TcpClient
{
public static void main(String[] args) throws Exception
{
//创建客户端的socket服务,指定目地主机和端口
Socket s = new Socket("125.221.182.196",10003);
//为了发送数据,应该获取socket流中的输出流
OutputStream out = s.getOutputStream();
out.write("tcp 哥们来了".getBytes());
//关闭 socket服务
s.close();
}
}


/*
需求:定义服务端接收数据并打印在控制台


服务端
1 建立服务端的socket服务 ServerSocket,并监听一个端口
2 获取连接过来的客户端对象
通过ServerSocket的accept方法 所以该方法是阻塞式的
3 客户端如果发过来数据,那么服务端要使用对应的客户端对象,
并获取客户端的读取流,读取发送来的数据并打印在控制台
4 关闭服务端(可选)
*/






class TcpServer
{
public static void main(String[] args) throws Exception
{
//建立服务端的ServerSocket服务并监听端口
ServerSocket ss = new ServerSocket(10003);

//通过accept方法获取连接过来的客户端对象
Socket s = ss.accept();

//获取客户端发送来的数据,那么要使用客户端对象的读取流来获取数据
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String ip = s.getInetAddress().getHostAddress();
int port = s.getPort();
System.out.println(ip+":"+port+"-->"+new String(buf,0,len));
s.close();
ss.close();
}
}




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


import java.net.*;
import java.io.*;
 
 
/*
客户端 
1 建立socket对象,指定要连接的主机和端口
2 获取socket流中的输出流,将数据写到该流中,通过网络发送给服务端
3 获取socket流中的输入流,将服务端反馈的数据获取到并打印
4 关闭客户端资源
*/
 
class TcpClient
{
public static void main(String[] args) throws Exception
{
Socket s  = new Socket("125.221.182.196",10000);
OutputStream out = s.getOutputStream();
out.write("hello,I am client.".getBytes());
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
}
}


/*
需求:定义服务端接收数据并打印在控制台


服务端
1 建立服务端的socket服务 ServerSocket,并监听一个端口
2 获取连接过来的客户端对象
通过ServerSocket的accept方法 所以该方法是阻塞式的
3 客户端如果发过来数据,那么服务端要使用对应的客户端对象,
并获取客户端的读取流,读取发送来的数据并打印在控制台
4 关闭服务端(可选)
*/






class TcpServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10000);
Socket s = ss.accept();
InputStream in = s.getInputStream();

String ip = s.getInetAddress().getHostAddress();
int port = s.getPort();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(ip+":"+port+"-->"+new String(buf,0,len));
OutputStream out = s.getOutputStream();
out.write("I get it.".getBytes());

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


126 Tcp练习


//接收客户端消息并转换为大写分别发送回去
//由于是文本所以使用字符流,注意两个问题:
1  BufferedWriter 自带缓冲区 需要flush 否则阻塞
2 readLine() 方法要读到换行符 newLine() 才能返回 否则一直阻塞
基于以上两个原因 Socket编程中建议用printWriter 来代替BufferedWriter
printWriter 构造函数中可以开启自动刷新和有println功能


import java.net.*;
import java.io.*;
 
 
class TcpClient
{
public static void main(String[] args) throws Exception
{
Socket s  = new Socket("125.221.182.196",10000);
 
 
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
String line  = null;


while((line=br.readLine()) != null)
{
out.println(line);
if("over".equals(line)) break;
line  = in.readLine();
System.out.println("getMsg:");
System.out.println(line);
}
br.close();
s.close();
}
}


/*
需求: 建立一个多线程的服务器
可以接收多个客户端 
打印客户端消息 并且转换为大写返回过去
*/






class TcpServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10000);
while(true)
{
Socket s = ss.accept();
new Thread(new TcpThread(s)).start();
}

}
}


class TcpThread implements Runnable
{
private Socket s;
TcpThread(Socket s)
{
this.s = s;
}

public void run()
{
try
{
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
// BufferedWriter bout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
String ip = s.getInetAddress().getHostAddress();
int port = s.getPort();
System.out.println(ip+":"+port+"建立连接");
 
while(true)
{
String str = in.readLine();
if("over".equals(str))
{
System.out.println(ip+":"+port+"断开连接");
break;
}
System.out.println(ip+":"+port+"->"+str);
out.println(str.toUpperCase());
}
s.close();
}
catch(Exception e)
{
throw new RuntimeException("服务器接收发生异常");
}

}
}


127 Tcp 复制文件
 
import java.net.*;
import java.io.*;
 
 //上传123.java到服务端
class TcpClient
{
public static void main(String[] args) throws Exception
{
Socket s  = new Socket("125.221.182.196",10000);
 
 
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("123.java")));
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
 
String line  = null;
while((line=br.readLine()) != null)
{
out.println(line);
}
//发完数据要给服务端一个结束的信息
//out.println("over");
s.shutdownOutput(); //关闭socket的输出流  readLine时就知道到达流的末尾返回null了
System.out.println(in.readLine()); //打印服务器的返回信息

br.close();
s.close();
}
}


/*
服务端:
将客户端上传的文件保存起来
并返回上传成功
*/






class TcpServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10000);
while(true)
{
Socket s = ss.accept();
new Thread(new TcpThread(s)).start();
}

}
}


class TcpThread implements Runnable
{
private Socket s;
TcpThread(Socket s)
{
this.s = s;
}

public void run()
{
try
{
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
PrintWriter fileWriter = new PrintWriter(new FileOutputStream("copy.txt"),true);
String ip = s.getInetAddress().getHostAddress();
int port = s.getPort();
System.out.println(ip+":"+port+"建立连接");
String line = null;
while((line=in.readLine()) != null)
{
// if("over".equals(line)) break;
fileWriter.println(line);
}

out.println("文件上传成功");
System.out.println("断开与"+ip+":"+port+"连接");

fileWriter.close(); //操作文件的流要close
s.close(); //Socket 要close ,其中的io流也会自动close
}
catch(Exception e)
{
throw new RuntimeException("服务器接收发生异常");
}

}
}




128 上传图片


// 将图片上传 需要使用字节流 否则会传输后打不开
 
import java.net.*;
import java.io.*;
 
 //上传123.java到服务端
class TcpClient
{
public static void main(String[] args) throws Exception
{
Socket s  = new Socket("125.221.182.196",10000);
FileInputStream fs = new FileInputStream("client.jpg");
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();

byte[] buf = new byte[1024];
int len = 0;
while((len=fs.read(buf)) != -1)
{
out.write(buf);
}
s.shutdownOutput(); //告诉服务端写完了

len = in.read(buf);
System.out.println(new String(buf,0,len));
fs.close();
s.close();
}
}


/*
服务端:
将客户端上传的文件保存起来
并返回上传成功
*/


class TcpServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10000);
while(true)
{
Socket s = ss.accept();
new Thread(new TcpThread(s)).start();
}

}
}


class TcpThread implements Runnable
{
private Socket s;
TcpThread(Socket s)
{
this.s = s;
}

public void run()
{
try
{
FileOutputStream fis = new FileOutputStream(Thread.currentThread().getId()+".jpg");
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = -1;
while((len=in.read(buf))!=-1)
{
fis.write(buf);
}
out.write("上传成功".getBytes());
fis.close();
s.close();
}
catch(Exception e)
{
throw new RuntimeException("服务器接收发生异常");
}

}
}


129 登录


 
import java.net.*;
import java.io.*;
 
class TcpClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("125.221.182.196",10000);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true); //一定要注意写自动刷新

boolean flag = false;
String line = null;
for(int n=0;n<3;n++)
{
System.out.println("请输入你的ID:");
line = br.readLine();
if(line==null) continue;
if(line.equals("")) continue;
out.println(line);
System.out.println("已发送:"+line);
line = in.readLine();
if("success".equals(line))
{
System.out.println("登录成功");
flag = true;
break;
}
}


br.close();
s.close();

}
}


/*
服务端:
使用一个文本存储id信息,比较客户端发来的信息.核对是否能够登录
 
*/


class TcpServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10000);
while(true)
{
Socket s  = ss.accept();
new Thread(new TcpThread(s)).start();
}

}
}


class TcpThread implements Runnable
{
private Socket s;
TcpThread(Socket s)
{
this.s = s;
}

public void run()
{
try
{
String ip = s.getInetAddress().getHostAddress();
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
 
String line = null;
String text = null;
all:for(int i=0; i<3;i++)
{
line = in.readLine();
System.out.println(ip+"发送"+line+"尝试登录");
if(line == null ) continue;

boolean flag = false;
BufferedReader br = new BufferedReader(new FileReader("id.txt"));
while((text=br.readLine()) != null)
{
if(line.equals(text))
{
flag = true;
break;
}
}
br.close();
if(flag) 
{
out.println("success");
System.out.println(ip+"登录成功");
break;
}
else
{
out.println("fail");
System.out.println(ip+"登录失败");
}
  }

s.close();
}
catch(Exception e)
{
throw new RuntimeException("服务器接收发生异常");
}

}
}


130 客户端是浏览器, 服务器自定义


import java.net.*;
import java.io.*;
 
//网页服务器 可以让浏览器访问
class TcpServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss =new ServerSocket(10000);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"enter");

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);
out.println("<font color='red' size='7'>客户端你好aaaa</font>");


s.close();
ss.close();

}
}
 
131 浏览器访问服务器的流程
1 浏览器 向服务器发送Get请求 
其中信息有:
GET  / HTTP/1.1 请求信息和浏览器版本
Accept: * 浏览器支持的文件格式
Accept-Language: zh-cn 浏览器支持语言
Accept-Encoding: gzip, deflate 支持压缩类型
User-Agent: 用户信息
Host: 125.221.182.196:10000  访问的IP与端口 (因为一个地址可能对应多个网页应用)
Connection: Keep-Alive 连接类型
空行
请求信息体


GET / HTTP/1.1
Accept: */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload
18; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727)
Host: 125.221.182.196:10000
Connection: Keep-Alive



自定义浏览器 dos版
 //自定义浏览器
import java.net.*;
import java.io.*;
 
class MyIE
{
public static void main(String[] args) throws Exception
{
 Socket s = new Socket("125.221.182.196",10000);
 PrintWriter out = new PrintWriter(s.getOutputStream(),true); //一定要注意写true
 out.println("GET / HTTP/1.1");
 out.println("Accept: */*");
 out.println("Accept-Language: zh-cn");
 out.println("Host: 125.221.182.196:10000");
 out.println("Connection: closed");
 out.println();
 out.println();
 s.shutdownOutput();
 
 BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
 String line = null;
 while((line=in.readLine()) != null)
 {
System.out.println(line);
 }
 
 s.close();
}
 
public static void  sop(Object obj)
{
System.out.println(obj);
}
}


132 图形化的自定义浏览器


133  URL
URL(String spec) 
          根据 String 表示形式创建 URL 对象。 
URL(String protocol, String host, int port, String file) 
          根据指定 protocol、host、port 号和 file 创建 URL 对象。 


 String getFile() 
          获取此 URL 的文件名。 
 String getHost() 
          获取此 URL 的主机名(如果适用)。 
 String getPath() 
          获取此 URL 的路径部分。 
 int getPort() 
          获取此 URL 的端口号。 
 String getProtocol() 
          获取此 URL 的协议名称。 

import java.net.*;
 


class URLDemo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("http://edu.csdn.net/main/feature/bxd_25.shtml/?name=a8887396&age=23");
System.out.println(url.getProtocol()); //http

System.out.println(url.getHost()); //edu.csdn.net 


System.out.println(url.getPort()); // -1 如果是-1 则使用默认端口
System.out.println(url.getDefaultPort()); //80

System.out.println(url.getPath()); // /main/feature/bxd_25.shtml/

System.out.println(url.getFile()); // /main/feature/bxd_25.shtml/?name=a8887396&age=23  带参数

System.out.println(url.getQuery()); //name=a8887396&age=23 参数
}
}


134 URLConnection
URL类有个方法:
 URLConnection openConnection() 
          返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。 
 


import java.net.*;
import java.io.*;


class URLConDemo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("http://edu.csdn.net/main/feature/bxd_25.shtml");
 
URLConnection con = url.openConnection();
//System.out.println(con);
InputStream in = con.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
//将只得到网页正文 ,不再有信息头
}
}


133 小知识点
public ServerSocket(int port,int backlog) 可以指定连接队列长度




134 正则表达式
符合一定规则的表达式
作用: 用于专门操作字符串




/*
对QQ号码进行校验 
要求: 5~15位 0不能开头 只能是数字
*/


1 传统方法
 
 
class Demo
{
public static void main(String[] args) throws Exception
{
System.out.println(checkQQ("1111111111111111111111111111111111111"));
}

public static boolean checkQQ(String qq)
{
int len = qq.length();
if(len>=5 && len <=15)
{
if(!qq.startsWith("0"))
{
try
{
long l = Long.parseLong(qq); 
if(l >= 10000 && l<= 99999999999999L)
{
return true;
}
}
catch(NumberFormatException e)
{
return false;
}
 
}
}
return false;
}
}
 
 
 
 


 135 正则表达式 -- 匹配
 1 匹配 String matches方法 用规则匹配整个字符串
 
 x 字符 x 
 [abc] a或者b或者c
 [^abc] 非abc其中一个
 [0-9] 或者 \d 数字
 [a-zA-Z] 字母  
 . 任意字符
\w 单词字符:[a-zA-Z_0-9] 
\W 非单词字符:[^\w] 
 
 ? 0或者1次
* 0或者n次
+ 1次或者一次以上
{n} 恰好n次
{n,} 至少n次
{n,m} n~m次


() 捕获组 后面也可以使用数量词
\n 任何匹配的 nth 捕获组


在正则表达式中的所有转义 到了字符串中都要多加一个反斜杠
 
/*
对QQ号码进行校验 
要求: 5~15位 0不能开头 只能是数字
*/
class Demo
{
public static void main(String[] args) throws Exception
{
System.out.println(checkQQ("a1111112"));
System.out.println(checkTel("18691115514"));
}

public static boolean checkQQ(String qq)
{
String regex = "[1-9][0-9]{4,14}";
if(qq.matches(regex))
{
return true;
}
else
return false;
}

//匹配 13  15 18 开头的手机号
public static boolean checkTel(String tel)
{
String regex = "1[358]\\d{9}";
if(tel.matches(regex))
{
return true;
}
else
return false;

}
}
 


 
136 正则表达式 -- 切割
 String[] split(String regex) 
          根据给定正则表达式的匹配拆分此字符串。 
 
class Demo
{
public static void main(String[] args) throws Exception
{
Split1("zhangsan    lisi wangwu  haha");
System.out.println();
Split2("zhangsan.lisi.wangwu");
System.out.println();
Split3("c:\\abc\\a.txt");
System.out.println();
Split4("123aasdsdzzwewuusdd2ddd1");
}

//多个空格分割
public static void Split1(String str)
{
String regex = " +"; //多个空格
String[] arr = str.split(regex);

for(String s : arr)
{
System.out.println(s);
}
}

//以.分割
public static void Split2(String str)
{
String regex = "\\."; // 以点来分割
// 原因: 正则表达式中的.是任意字符的意思 与 本意不同
// \. 表示正则表达式中的.
// 但在字符串中 需要为\ 再加一个\ 所以是\\.
String[] arr = str.split(regex);
for(String s : arr)
{
System.out.println(s);
}
}

// 以\\切割 c:\\abc\\a.txt
public static void Split3(String str)
{
String regex = "\\\\"; // 以点来分割
String[] arr = str.split(regex);
for(String s : arr)
{
System.out.println(s);
}
}

//叠词切割 需要使用匹配组
public static void Split4(String str)
{
String regex = "(.)\\1+";
String[] arr = str.split(regex);
for(String s : arr)
{
System.out.println(s);
}
}

}
 
137 正则表达式- 替换
String类
String replaceAll(String regex, String replacement) 
          使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 
 


class Demo
{
public static void main(String[] args) throws Exception
{
//将字符串中的一串(数量大于>5)数字转换成#
replace("hello13899001232goobye23","\\d{5,}","#");
/将叠词替换成# uu-># ccc-> # 9999-># 
replace("13sdsuuosdscco90","(.)\\1+","#");
}

 
public static void replace(String str,String reg,String newstr)
{
str = str.replaceAll(reg,newstr);
System.out.println(str);
}
 
}
 
 
138 正则表达式-获取子串 


Pattern 和 Matcher 对象属于 java.util.regex.包中 需要导入包
相关函数:
1 Pattern对象的获取 使用静态函数 将规则封装成对象
Pattern p = Pattern.compile("regex...");
static Pattern compile(String regex) 
          将给定的正则表达式编译到模式中。 
2 Matcher对象的获取
Matcher m = p.matcher("adsdsdswewqeqeqweqw");
 Matcher matcher(CharSequence input) 
          创建匹配给定输入与此模式的匹配器。 
3 Matcher 类中的方法
1 是否整串匹配
 boolean matches()
          尝试将整个区域与模式匹配。 
2 查找匹配的子字符串
 boolean find()  
          尝试查找与该模式匹配的输入序列的下一个子序列。 
 boolean find(int start) 
          重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列。 
find 和 matches 都会改变比较器的当前位置,所以有个find(int)来重置比较器
 String group() 
          返回由以前匹配操作所匹配的输入子序列。 


 int start() 
          返回以前匹配的初始索引。 
 int end() 
          返回最后匹配字符之后的偏移量。  




//查找字符串中连续三个字母的子串
import java.util.regex.*;
 
class Demo
{
public static void main(String[] args) throws Exception
{
getDemo();
}

public static void getDemo()
{
String str= "231 sdsdsd 3ewd1 sd2 sds123 13 42d";
String reg = "\\b\\w{3}\\b"; \\ \b是词语边界
System.out.println(str);
//将规则封装成模式对象
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()); //获取上一个匹配处的开始和结束位置
}

}
}
 
 正则表达式匹配邮箱
 
 "\\w+\\@\\w+(\\.\\w+)+"
 sdsd@sina.com.cn
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值