网络编程,会用到IP和端口,在TCP和UDP通信时都会用到端口。还有需要了解的就是URL。
work_1就是认识URL,这样看URL就是包含了好多东西的一个对象
package Java的网络编程;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
/*使用URL相关用例*/
public class work_1_URLBaidu {
public static void main(String[] args) {
try{
//实例化URL对象
URL url=new URL("http://www.baidu.com/index.htm?sw=天气");
System.out.println("权限信息:"+url.getAuthority());
try {
System.out.println("对象内容"+url.getContent());
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("默认端口:"+url.getDefaultPort());
System.out.println("文件名:"+url.getFile());
System.out.println("主机名:"+url.getHost());
System.out.println("URL路径:"+url.getPath());
System.out.println("端口号:"+url.getPort());
System.out.println("协议名:"+url.getProtocol());
System.out.println("查询信息:"+url.getQuery());
System.out.println("URL锚点:"+url.getRef());
System.out.println("URL使用者:"+url.getUserInfo());
} catch(MalformedURLException e){
e.printStackTrace();
}
}
}
运行结果
————————————
权限信息:www.baidu.com
对象内容sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@5c647e05
默认端口:80
文件名:/index.htm?sw=天气
主机名:www.baidu.com
URL路径:/index.htm
端口号:-1
协议名:http
查询信息:sw=天气
URL锚点:null
URL使用者:null
————————————
就像上面展示出来的端口,文件名,主机名and so on
work_2挺好的,带你认识必须要掌握的InetAddress对象
package Java的网络编程;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
/*这个应该主要用在获取地址吧*/
public class work_2_testInteAddress {
public static void main(String[] args) throws IOException {
InetAddress addr=InetAddress.getLocalHost(); //获取本机IP
System.out.println("Local host:"+addr);
addr=InetAddress.getByName("baidu.com"); //指定服务的一个IP
System.out.println("Baidu:"+addr);
InetAddress[] addrs=InetAddress.getAllByName("baidu.com"); //指定服务的所有IP
for (int i=0;i<addrs.length;i++)
System.out.println("baidu:"+addrs[i]+"number:"+i);
System.out.println(InetAddress.getByName("localhost").isReachable(1000)); //获取远程主机可达性
}
}
运行结果
————————————
Local host:ZY-dream/192.168.59.1
Baidu:baidu.com/111.13.101.208
baidu:baidu.com/111.13.101.208number:0
baidu:baidu.com/123.125.114.144number:1
baidu:baidu.com/180.149.132.47number:2
baidu:baidu.com/220.181.57.217number:3
true
————————————
很多人如果不知道自己本机的IP地址,到这里看看。
但是现在不明白为什么baidu.com为什么有多个地址?
因为说是百度有钱,有好多web服务端,所以就有很多地址。dns解析会得到离我最近的地址。
work_3是带socket的使用,检查本机指定范围内的端口是否已经使用
package Java的网络编程;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* 检查某个范围中的端口是否被占用/
*/
public class work_3_MyCheckPort {
public static void main(String[] args) {
for (int i=1;i<=256;i++){
try {
InetAddress local=InetAddress.getLocalHost();
Socket socket=new Socket(local, i);
System.out.println("本机已经使用了端口:"+i); //如果不输出异常,则输出该端口已经被占用
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
//因为端口被占用时,会大量地抛出这个异常,可以将这个异常注释
//e.printStackTrace();
}
}
System.out.println("检查完毕");
}
}
说是检查的端口范围比较大,所以费时间点,最后会是输入80,可以向上看work_1的默认端口就是80。
socket就是与服务器建立链接,就是一个通信对象,用这可以接受服务端,又可以开启客户端。我们将在下面work_4看到
work_4是使用TCP通信编写聊天软件,目前看到的是基于两个窗口控制台的。
public static void main(String[] args) {
try{
ServerSocket server=null;
try{
server=new ServerSocket(8887);
System.out.println("服务端已经准备好,若要退出输入bye");
} catch (Exception e){
System.out.println("不能创建网络监听器,原因是:"+e.getMessage());
}
Socket socket=null;
try{
socket=server.accept();
} catch (Exception e){
System.out.println("服务出错,原因是:"+e.getMessage());
}
Scanner input=new Scanner(System.in);
PrintWriter os=new PrintWriter(socket.getOutputStream());
BufferedReader bfr=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String works=input.next();
while (!"bye".equals(works)){
os.println(works);
os.flush();
System.out.println("服务器:"+works);
System.out.println("客户端:"+bfr.readLine());
works=input.next();
}
os.close();
bfr.close();
socket.close();
input.close();
}catch (Exception e){
e.printStackTrace();
}
}
ServerSocket链接端口,准备服务端的对象。
然后用Socket创建通信对象,和Server进行应和(accept)
读写输入输出流的时候,用到的是printwriter和bufferedreader
以上就是我现在总结服务端的三大步。
public static void main(String[] args) {
try {
Socket socket=new Socket("127.0.0.1", 8887);
Scanner inpur=new Scanner(System.in);
System.out.println("输入你想要说的话,如果要退出的话,输入bye");
PrintWriter os=new PrintWriter(socket.getOutputStream());
BufferedReader bfr=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String workds=inpur.next();
while (!"bye".equals(workds)){
os.println(workds);
os.flush();
System.out.println("客户端:"+workds);
System.out.println("服务器:"+bfr.readLine());
workds=inpur.next();
}
os.close();
bfr.close();
socket.close();
inpur.close();
} catch (Exception e) {
e.printStackTrace();
}
}
对于客户端,需要一定要把Socket里的端口和服务端里的端口保持一致
之后,进行输入输出流读写,同服务端操作即可
是在控制台上进行的,幸好eclipse的Display Selected Console可以实现两个控制台的切换。
这里,一个主要学会用Socket和ServerSocket,而是对于输入输出流的操作例如printwriter和bufferedreader
然后,这个work_5来到了UDP,通过UDP通信编写聊天软件。
在网上看TCP和UDP的区别后,说的很多,就是UDP很随意,很直接的传输数据,所以这个也就在Swing上来演示。TCP好歹能先做好一个铺垫,能安全点,复杂点。
package Java的网络编程;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/*
* 哇哦哦来到了UDP通信编写聊天程序
* 这次还多了界面
* 赶快着手试试吧*/
public class work_5_UDPMessage extends JFrame implements ActionListener{
private static final long serialVersionUID=1L;
private JTextArea text;
private JTextField iptext;
private JTextField sendtext;
private JButton send;
private DatagramSocket socket; //数据报套接字
private JScrollBar vsBar; //滚动条
public work_5_UDPMessage(){
setTitle("UDP聊天程序");
setBounds(100, 100, 500, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //默认关闭操作为退出程序
text=new JTextArea();
text.setEditable(false);
JScrollPane textpanel=new JScrollPane(text);
vsBar=textpanel.getVerticalScrollBar();
add(textpanel,BorderLayout.CENTER);
JPanel panel=new JPanel();
BorderLayout pl=new BorderLayout();
pl.setHgap(5);
panel.setLayout(pl);
iptext=new JTextField("192.166.1.100");
panel.add(iptext,BorderLayout.WEST);
sendtext=new JTextField();
sendtext.addActionListener(this);
panel.add(sendtext, BorderLayout.CENTER);
send=new JButton("发送");
panel.add(send, BorderLayout.EAST);
add(panel,BorderLayout.SOUTH);
setVisible(true);
server();
send.addActionListener(this);
}
public void server() {
try {
socket=new DatagramSocket(6666);
byte[] buf=new byte[1024];
final DatagramPacket dp=new DatagramPacket(buf, buf.length); //创建接收数据的数据包
Runnable myrun=new Runnable() {
public void run() {
while (true){
try {
Thread.sleep(100);
socket.receive(dp); //接受数据包
int length=dp.getLength();
String message=new String(dp.getData(), 0, length);
String ip=dp.getAddress().getHostAddress();
if (!InetAddress.getLocalHost().getHostAddress().equals(ip))
text.append("远程-"+ip+":\n"+message+"\n");
vsBar.setValue(vsBar.getMaximum());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
};
new Thread(myrun).start();
} catch (SocketException e) {
e.printStackTrace();
}
}
public void actionPerformed(ActionEvent e) {
sendMess();
}
private void sendMess(){
try {
String ip=iptext.getText();
InetAddress address=InetAddress.getByName(ip);
byte[] data=sendtext.getText().getBytes();
DatagramPacket dp=new DatagramPacket(data,data.length,address,6666); //定义数据包
String myip=InetAddress.getLocalHost().getHostAddress(); //获取本机ip
text.append("本机-"+myip+":\n"+sendtext.getText()+"\n");
socket.send(dp); //发送数据包
sendtext.setText(null);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
}
package Java的网络编程;
import javax.swing.JFrame;
public class work_5_test {
public static void main(String[] args) {
JFrame f=new work_5_UDPMessage();
}
}
在server函数里面用到了线程,里面还使用了while无限循环,也是因为和JTexArea,JTextFiled接受显示信息有关,这个UDP通信确实到现在没彻底搞明白
初始化对话框的默认构成函数倒是很明白,以至于在后来的改进TCP通信时会用了。
主要使用的是DatagramSocket,
然后配合DatagramPacket其的发送和接受方法。即可。
总之,今天对网络编程这块肯定是比以前有所认识了,知道了使用什么进行数据传送,怎样输入读取数据。