- 浏览: 16579 次
- 性别:
- 来自: 广州
最新评论
Socket网络编程 网络协议 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聊天程序 通过键盘录入获取要发送的消息. BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 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(); } } } 注意接收数据的时候会出现阻塞-->出现阻塞之后.您多线程怎么跑都运行不了.必须要等我发送端发送数据过去才可以. 获取时间: String str = "本地发送于 " + DateFormat.getInstance().format(new Date()) + "\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; } } } 心得与总结: 多线程需要复习--> 首先在接收数据的时候.会遇到阻塞-->必须要运行一下发送端程序.. 时间这个类也得复习.. 明天早上起来的任务-->必须要回顾知识..和敲写多一次这个程序. 今天的时间掌握得还是比较不好的~~希望下次好好努力改正..需要认真去对待每一件事.. 多背下单词.
发表评论
-
javase_22(TCP的理解)
2012-09-02 19:43 647TCP传输 Socket(客户端)和ServerSocket( ... -
javase_20(Awt初步认识)
2012-08-27 01:00 1029多线程的再度复习.class package com.jav ... -
javase_19(多线程)
2012-08-24 23:32 876进程: 进程是具有一定独立功能的程序关于某个数据集合上的一次 ... -
javase_18(回顾与反射机制学习)
2012-08-20 11:58 462AM上午总结: package com.ja ... -
javase_17(IO的总结)
2012-08-20 11:55 1070所有的流在使用完毕时,都需要调用close方法进行关流,释放资 ... -
javase_16(其它流)
2012-08-20 11:52 912IO包中的其他流: 1.打印流 a)PrintWri ... -
javase_16(其它流)
2012-08-20 11:38 0IO包中的其他流: 1.打印流 a)PrintWri ... -
javase_15(File类的应用)
2012-08-19 00:07 902File类:用来将文件或者 ... -
javase_14(字节流)
2012-08-19 00:00 726字节流的抽象基类: InputStream(输入) ... -
javase_13(字符流)
2012-08-19 00:00 624IO(Input OutPut)流 IO流用来处理设备 ... -
javase_12(集合+时间对象)
2012-08-19 00:00 584Map集合 1.Map存储了一系列键值的映射关系2.M ... -
javase_11(集合的理解)
2012-08-19 00:00 889集合类: 为什么使 ... -
javase_10(String类日常操作)
2012-08-18 09:40 842第一: package com.ja ... -
javase_09(面向对象总结)
2012-08-18 09:39 917Java的环境配置 day01 1. 环 ... -
javase_08(基础面试题)
2012-08-18 09:38 765面试题:请说说抽象类和接口的区别 抽象类,使用abstrac ... -
javase_07(继承与设计模式)
2012-08-18 09:36 646/* 子类对象的实 ... -
javase_06(面向对象)
2012-08-18 09:29 704/* 内部类: .在类中定义的类我们称之为内部类, ... -
javase_05(面向对象)
2012-08-16 11:25 0一.构造函数的定义与 ... -
javase_05(面向对象)
2012-08-16 11:22 829一.构造函数的定义与作用 1.函数的名次与类同名2.没有 ... -
javase_04(面向对象)
2012-08-16 11:21 559面向对象:一种编程思想,使用对象来描述生活中的事物:面向对象的 ...
相关推荐
csdn有一个下载包含HtmlAdaptorServer这个class,不过不知道是不是官方的,而且跟网上介绍的资料不一样,所以自己去oracle官网找着下载...http://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html
JavaSE语法基础_19-变量的作用域.mp443--第01单元-JavaSE语法基础_20-交换变量.mp444--第01单元-JavaSE语法基础_21-算术运算符.mp445--第01单元-JavaSE语法基础_22-逻辑运算符.mp446--第01单元-JavaSE语法基础_23-...
JavaSE语法基础_19-变量的作用域.mp443--第01单元-JavaSE语法基础_20-交换变量.mp444--第01单元-JavaSE语法基础_21-算术运算符.mp445--第01单元-JavaSE语法基础_22-逻辑运算符.mp446--第01单元-JavaSE语法基础_23-...
JavaSE语法基础_19-变量的作用域.mp443--第01单元-JavaSE语法基础_20-交换变量.mp444--第01单元-JavaSE语法基础_21-算术运算符.mp445--第01单元-JavaSE语法基础_22-逻辑运算符.mp446--第01单元-JavaSE语法基础_23-...
JavaSE语法基础_19-变量的作用域.mp443--第01单元-JavaSE语法基础_20-交换变量.mp444--第01单元-JavaSE语法基础_21-算术运算符.mp445--第01单元-JavaSE语法基础_22-逻辑运算符.mp446--第01单元-JavaSE语法基础_23-...
JavaSE语法基础_19-变量的作用域.mp443--第01单元-JavaSE语法基础_20-交换变量.mp444--第01单元-JavaSE语法基础_21-算术运算符.mp445--第01单元-JavaSE语法基础_22-逻辑运算符.mp446--第01单元-JavaSE语法基础_23-...
JavaSE语法基础_19-变量的作用域.mp443--第01单元-JavaSE语法基础_20-交换变量.mp444--第01单元-JavaSE语法基础_21-算术运算符.mp445--第01单元-JavaSE语法基础_22-逻辑运算符.mp446--第01单元-JavaSE语法基础_23-...
JavaSE_Android精华版-----中文文档API,JavaSE_Android精华版-----中文文档API
【MLDN_JAVASE_文档】是一份针对Java SE(标准版)的全面学习资源,由MLDN(可能是指微软学习网络或类似的教育平台)提供。这个文档集合旨在帮助初学者和进阶者掌握Java编程语言的基础知识。Java SE是Java平台的核心...
JavaSE(Java Standard Edition)是Java编程语言的核心部分,它提供了编写桌面应用程序所需的基础类库。这份"JavaSE总结文档.rar"包含了一份个人在复习JavaSE时编写的笔记,覆盖了多个主题,旨在巩固和深化对Java...
Java SE中的Java IO和File类是Java编程中非常重要的部分,尤其对于处理文件和目录的操作。在"VIP09_JavaSE_JavaIO_File_day0307-1.rar"这个压缩包中,...为了深入学习,建议结合该压缩包内的材料进行实践操作和学习。
(1)NotePad++设置:菜单栏->设置->语言格式设置->设置字体consolas。设置字号大小等。 编码:编码字符集->中文->GB2312(中文的字符集)。菜单栏--------->编码--------->编码字符集-------->中文------------->GB...
### JavaSE内部学习笔记知识点概览 #### 一、Java语言概述 - **1.1 基础常识** - **软件分类**:软件分为系统软件和应用软件两大类。系统软件支持计算机硬件正常工作,包括操作系统、设备驱动程序等;应用软件则...
### JavaSE_集合.pdf 关键知识点详解 #### 一、集合与数组的区别 - **固定与动态**: 数组的长度是固定的,一旦声明后就不能改变;而集合的大小可以动态扩展,更适合处理不确定数量的数据。 - **数据类型**: 数组...
一个javaSE的api文档。这是在网上找了接近两个小时后的结果。 java官网:不提供javaSE api 中英文对照文档。特别烦。 某资源网站:下载链接混在一堆广告链接中(广告图片上还写着下载请点这里,特别烦),下了一堆...
这个名为"javase_day04_v1_pm_all.zip"的压缩包文件显然是一个教学资源集合,旨在帮助学习者巩固和深化Java SE(标准版)的知识。"day04"的命名可能意味着这是连续课程中的第四天内容,通常涵盖了一些基本概念的深入...
这个编程资料包涵盖了JavaSE的学习资源,旨在帮助开发者掌握Java的基础知识、集合框架、IO流等关键概念。 首先,Java基础知识是学习JavaSE的起点。这包括了Java语法、数据类型、控制结构(如if语句、for循环、while...