javase_21(DUp的学习-->*)
2012-09-03 20:51
169 查看
Socket网络编程
网络协议
IP地址与端口号
本地回路IP: 127.0.0.1
有效端口:0-65535(尽量使用1024个以上-->1024个以上的被占用的概率比较低)
UDP与TCP(协议)
Udp:用户数据包协议,面向无连接,不保证数据的可靠性,不安全,速度快
Tcp:传输数据协议,面向连接,提供可靠无差错的协议,安全,三次握手.
UDP传输:
DatagramSocket 和:DatagramPacket
建立发送端,接收端
建立数据包,
调用Socket的发送接收方法.
关闭Socket
发送端与接收端是两个独立运行的小程序.
发送端:
在发送端,要在数据包对象中明确的IP与端口.
接收端:要指定监听的端口
UDP聊天程序
通过键盘录入获取要发送的消息.
将发送和接收分别封装到两个线程中,main()线程, 和 new Thread()线程
使用了循环的聊天方式(必须要开两个窗口)
-->我们需要做到的效果-->多线程实现.实现两边通信..
多线程的效果:
注意接收数据的时候会出现阻塞-->出现阻塞之后.您多线程怎么跑都运行不了.必须要等我发送端发送数据过去才可以.
心得与总结:
多线程需要复习-->
首先在接收数据的时候.会遇到阻塞-->必须要运行一下发送端程序..
时间这个类也得复习..
明天早上起来的任务-->必须要回顾知识..和敲写多一次这个程序.
今天的时间掌握得还是比较不好的~~希望下次好好努力改正..需要认真去对待每一件事..
多背下单词.
网络协议
IP地址与端口号
本地回路IP: 127.0.0.1
有效端口:0-65535(尽量使用1024个以上-->1024个以上的被占用的概率比较低)
UDP与TCP(协议)
Udp:用户数据包协议,面向无连接,不保证数据的可靠性,不安全,速度快
Tcp:传输数据协议,面向连接,提供可靠无差错的协议,安全,三次握手.
UDP传输:
DatagramSocket 和:DatagramPacket
建立发送端,接收端
建立数据包,
调用Socket的发送接收方法.
关闭Socket
发送端与接收端是两个独立运行的小程序.
发送端:
在发送端,要在数据包对象中明确的IP与端口.
DatagramSocket ds = new DatagramSocket(); Byte[] by = "hello,net".getBytes();//转换成字节 DatagramPacket dp = new DatagramPacket(by,0,by.length,InerAddress.getByName(127.0.0.1),10000); //数据包打包起来 ds.send(dp); Ds.close();//关流
接收端:要指定监听的端口
datagramSocket ds = new datagramSocket(10000); byte [] buf = new byte[1024]; datagramPacket dp = new datagramPacket(buf,by.length); ds.receive(dp);//把内容接收到dp里面去 String str = new String(dp,getData(),0,dp.length()); System.out.println(str); ds.close();
UDP聊天程序
通过键盘录入获取要发送的消息.
1 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 2 br.readLine();
将发送和接收分别封装到两个线程中,main()线程, 和 new Thread()线程
发送端: import java.net.DatagramSocket; import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; class UdpSend { public static void main(String[]args) { DatagramSocket ds = null; try { ds = new DatagramSocket(); String line = "I Come as For China"; byte[]buf = line.getBytes();//转换成字节数组 DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),8888); ds.send(dp); } catch (IOException e) { e.printStackTrace(); }finally { if(ds!=null) ds.close();//关闭流 } } } 接收端: 当开始监听端口的时候,会出现阻塞,直到监听完毕: import java.net.DatagramSocket; import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; class UdpReceive { public static void main(String[] args) { //监听该端口 DatagramSocket ds = null; try { ds = new DatagramSocket(8888); DatagramPacket dp = new DatagramPacket(new byte[1024],1024); //它会发生阻塞功能,首先运行这个.他会监听端口 .. ds.receive(dp); byte[] buf = dp.getData(); String data = new String(buf,0,dp.getLength()); System.out.println(data); } catch (IOException e) { e.printStackTrace(); }finally { if(ds!=null) ds.close(); } } }
使用了循环的聊天方式(必须要开两个窗口)
发送端:() import java.net.DatagramSocket; import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.io.BufferedReader; import java.io.InputStreamReader; class MySend { public static void main(String[] args) { DatagramSocket ds = null; BufferedReader br = null; try { ds = new DatagramSocket(); DatagramPacket dp; br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("聊一下吧~~~"); while(true) { String line = br.readLine(); if("byte".equals(line))break;//如果return;就关闭不了流啦 byte[] buf = line.getBytes(); //必须要获取到正确的长度 dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),8888);//封装数据 ds.send(dp); } } catch (IOException e) { e.printStackTrace(); }finally { try { if(ds!=null) ds.close(); }finally { try { if(br!=null) br.close(); }catch(IOException e) { e.printStackTrace(); } } } } } 接收端: import java.net.DatagramSocket; import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.io.BufferedReader; import java.io.InputStreamReader; class MyReceive { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(8888);//监听端口号 DatagramPacket dp = new DatagramPacket(new byte[1024],1024); while(true) { ds.receive(dp);//接收数据 String data = new String(dp.getData(),0,dp.getLength()); if("byte".equals(data)) break; String ipHost = dp.getAddress().getHostName();//IP主机名字 String ipName = dp.getAddress().getHostAddress();//IP地址 int port = dp.getPort(); System.out.println(ipHost+"("+ipName+")"+" "+port); System.out.println(data); } if(ds!=null) ds.close(); } }
-->我们需要做到的效果-->多线程实现.实现两边通信..
多线程的效果:
import java.net.DatagramSocket; import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.InputStreamReader; class UdpChat { /* 利用多线程来实现程序 Thread-0接收数据 Main -主线程 发送数据 */ public static void main(String[] args) { new Thread(new MyChat()).start(); DatagramSocket ds = null; BufferedReader br = null; try { ds = new DatagramSocket(); br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("咱们来聊一下吧~~~"); while(true) { String line = br.readLine(); if(line.equals("byte")) break; byte[] buf = line.getBytes();//转换成字节数组 DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),9089); ds.send(dp); } } catch (IOException e) { e.printStackTrace(); } } } class MyChat implements Runnable { public void run() { DatagramSocket ds = null; try { ds = new DatagramSocket(9089); DatagramPacket dp = new DatagramPacket(new byte[1024],1024); while(true) { ds.receive(dp);//接收数据 byte[] buf = dp.getData(); String line = new String(buf,0,dp.getLength()); String ipStr = dp.getAddress().getHostAddress()+"From:"+dp.getAddress().getHostName();//主机名字 int port = dp.getPort(); System.out.println(ipStr+port+" -- ~~"+line); } } catch (IOException e) { e.printStackTrace(); }finally { if(ds!=null) ds.close(); } } }
注意接收数据的时候会出现阻塞-->出现阻塞之后.您多线程怎么跑都运行不了.必须要等我发送端发送数据过去才可以.
1 获取时间: 2 String str = "本地发送于 " + DateFormat.getInstance().format(new Date()) 3 + "\r\n" + data + "\r\n";
聊天程序案例分析 一、需求 1.软件的界面:实现窗体Frame、显示文本TextArea或List、发送按钮Button、IP输入TextField 2.聊天功能:实现发送端和接收端程序(多线程) 3.附加功能: 保存聊天记录、关闭软件 二、实现步骤 1.实现软件界面的设计 1)创建Frame,设置大小、位置、可见 f 2)创建一个TextArea文本域,用于显示文字 A 3)创建一个TextArea文本域,用于输入文字 input 3)创建一个TextField单行输入框用于输入Ip,B 4)创建一个Button按钮,用于发送信息,C 2.添加事件监听 1)为f添加窗口监听addWindowListener(WindowAdapter),关闭窗口 2)为按钮C添加鼠标监听 addMouseListener(MouseAdapter),监听点击事件,发送消息,调用sendMsg 3)为文本域A添加键盘监听 addKeyListener(KeyAdapter) , 监听按下事件keyPressed发送消息 sendMsg 3.实现发送端 sendMsg方法 1)创建DatagramSocket对象,绑定闲置端口 2)获取input中的内容,作为message 3)获取B中的内容,作为Ip,这里要判断,如果没填,默认指定255.255.255.255 4)创建DatagramPacket对象,打包数据,统一端口7888 5)发送数据 ds.send(dp) 6)将数据和时间显示在A,append方法 4.实现接收端程序 1)软件已运行就可以收数据了,所以在构造函数中开启新线程,运行接收端 new Thread(new Runnble()).start(); 2)在run方法中实现接收端程序 3)创建DatagramSocket对象,监听7888端口 4)准备数据包 5)接受数据,阻塞,这个要做在循环里面 ds.receive(dp) 6)获得数据和对方的Ip , new String(dp.getData(), 0, dp.getLength())\dp.getInetAddress().getHostAddress\(dp.getPort) 7)获得当前时间, DateFormat.getInstance().format(new Date()); 8)将数据显示在A,append方法 import java.awt.BorderLayout; import java.awt.Button; import java.awt.Frame; import java.awt.Panel; import java.awt.TextArea; import java.awt.TextField; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.FileWriter; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.text.DateFormat; import java.util.Date; class MyChatTest { public static void main(String[] args) { MyChatOne mc = new MyChatOne(); } } class MyChatOne { private Frame f; private TextArea disPlay,dataInput; private TextField ipInput;//IP地址的读取(单行文本可编程的组件) private Button senBtn; private boolean close = false; public MyChatOne() { f = new Frame(); f.setSize(370,500); f.setLocation(100,150); f.setResizable(false);//不可移动 disPlay = new TextArea(23,30); disPlay.setEditable(false);//不可编辑 dataInput = new TextArea(10,30); ipInput = new TextField(20); senBtn = new Button("发送(Ctrl+Enter)"); f.add(disPlay,"North"); f.add(dataInput,"Center"); Panel p = new Panel(new BorderLayout()); p.add(ipInput,"West");//西边 p.add(senBtn,"East");//北' f.add(p,"South");//南 f.setVisible(true); handEvent(); new Thread(new ReceiveInMyChat()).start(); } //监听 private void handEvent() { f.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e) { e.getWindow().dispose(); close = true; ipInput.setText("127.0.0.1");//阻塞,随便运行一下发送端就可以. } }); senBtn.addMouseListener(new MouseAdapter(){ public void mouseClicked(MouseEvent e) { sendMsg();//当您触发我的确定按钮.我需要做的事情.. } }); dataInput.addKeyListener(new KeyAdapter(){ //监听编辑器.当按下键盘并且+回车..你懂的.. public void keyPressed(KeyEvent e) { if(e.isControlDown()&&e.getKeyChar()=='\n') sendMsg(); } }); } private void sendMsg() { //实现发送端的程序 DatagramSocket ds = null; try { ds = new DatagramSocket(); String data = dataInput.getText();//获取里面的数据 String ip = ipInput.getText();//获取单行编辑条的内容 if(ip.length()==0) { ip = "127.0.0.1"; ipInput.setText(ip);//如果没有.我也必须往里面写入数据 } byte[] buf = data.getBytes();//获取字节数组 //封包 DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName(ip),8888);//封装数据 //发包 ds.send(dp); //将信息显示在display()这边 String str = "本地发送于 " + DateFormat.getInstance().format(new Date()) + "\r\n" + data + "\r\n"; disPlay.append(str);//追加内容到这边来 dataInput.setText("");//表示清空内容~ saveMessage(str); //等一下我们可以做一下聊天记录 } catch (IOException e) { e.printStackTrace(); }finally { if(ds!=null) ds.close(); } } //接收端咱们用多线程实现 class ReceiveInMyChat implements Runnable { @Override public void run() { DatagramSocket ds = null; try { ds = new DatagramSocket(8888);//指定需要监听的端口号 DatagramPacket dp = new DatagramPacket(new byte[1024],1024); while(true) { //阻塞-->必须要执行内容才可以到这一步.但我们到这一步.可以把多线程退出. ds.receive(dp); if(close) break;//跳出循环.多线程就会关闭 String data = new String(dp.getData(),0,dp.getLength()); String ip = dp.getAddress().getHostAddress()+"("+dp.getAddress().getHostName()+")"; String str = ip + " 发送于 " + DateFormat.getInstance().format(new Date()) + "\r\n" + data + "\r\n"; disPlay.append(str); saveMessage(str); } } catch (IOException e) { e.printStackTrace(); }finally { if(ds!=null) ds.close(); } } } /* 聊天记录的保存: */ private void saveMessage(String str) { FileWriter fw = null; try { fw = new FileWriter("d:/聊天记录.txt",true);//表示从后面追加 fw.write(str); } catch (IOException e) { e.printStackTrace(); } finally { try { if(fw!=null) fw.close();//关流. } catch (IOException e) { e.printStackTrace(); } } } } 多线程的回顾: package com.javami.kudyDemo.udpStudy; public class ThreadDemo { /** * 主要内容复习下多线程的回归,..主线程必须执行先~~ */ public static void main(String[] args) { new Thread(new MyThread()).start(); for(int i=0; i<10; i++) { System.out.println("主线程!!!"); } } } class MyThread implements Runnable { public void run() { int num = 0; while(true) { System.out.println("To Learn How"); num ++; if(num>10) break; } } }
心得与总结:
多线程需要复习-->
首先在接收数据的时候.会遇到阻塞-->必须要运行一下发送端程序..
时间这个类也得复习..
明天早上起来的任务-->必须要回顾知识..和敲写多一次这个程序.
今天的时间掌握得还是比较不好的~~希望下次好好努力改正..需要认真去对待每一件事..
多背下单词.
相关文章推荐
- Android学习 21->进度条之SeekBar和RatingBar
- JavaSE初学笔记之<nio的学习>
- 比较值得学习的sql语句_decode,to_char,TO_CHAR(sysdate,'MM'),(t.end_date,'HH24')>=21
- javase_22(TCP的学习-->)
- iOS学习笔记21-当工程中提示#import <libxml/parser.h>不存在时,只需要两部操作即可
- [置顶] JavaSE学习笔记_17:Java-Math&Random类
- CSS学习笔记之<!important>
- Linq学习__03__数据源是IEnumerable<T> 变量,Concat,匿名类,数组下标,返回字符串,group by,orderby
- Cocos2d-x学习笔记(十)-------->动作类
- C++基础学习教程(七)----类编写及类的两个特性解析--->多态&继承
- win32汇编 屏幕截图保存BMP 学习笔记<第二篇>之东拼西凑
- Cocos2d-x学习笔记(七)-------->Button控件
- R语言学习笔记之<进度条>
- OPENCV学习笔记3-7_RGB->YCbCr
- 基于HTK语音工具包 的学习<递进式>
- HTML学习 <3>
- html系统学习之三 <表格,列表,表单>
- <无线局域网媒体访问控制和物理层规范:汇聚无线控制技术规范>学习总结
- HTML学习 <4>
- Android Fragment 学习<1>