您的位置:首页 > 理论基础 > 计算机网络

黑马程序员_Java基础_网络编程_UDP传输协议编程,控制台聊天程序

2014-05-21 09:52 1206 查看
一,网络编程

1,网络通信概述:网络在我们生活中很常见,比如我们使用QQ,微信,MSN等聊天软件,都是通过网络进行数据传输的。实现这样的数据传输需要满足那些条件呢?能够满足这些条件的应用程序就可以看做是一个网络应用程序。当我们和别人之间使用这样的程序进行通信时,首先我们必须知道别人在哪里,知道别人的电脑主机地址,这个地址也就是我们很熟悉的IP地址。但是只知道别人的IP地址还不够,我们的电脑上安装了肯定不止一款通信软件,那么怎样才能把我这边通过QQ发送的消息发送到对方的QQ上,而不是微信上呢?这就要引入端口的概念,当我们找到别人的位置,也就是获取到别人的IP地址后,找到别人的主机,然后找相对应的端口,我用QQ发送消息,只有找到对方的QQ所对应的端口,发送到该端口,别人的QQ才能处理我发送的消息数据。

2,端口:网络中的端口是逻辑端口,其实就是每个应用程序对应的数字标示,比如QQ对应的端口是一个数字,微信对应的端口又是另外一个数字,这些数字之间不会冲突。并不是我们常见的诸如网线端口,USB端口的物理端口。常见端口:WEB服务端口是80,tomcat服务器默认端口:8080,mySQL默认是3306,当然这些是可以修改的,一旦端口被占用,另一个网络程序就不能使用该端口了。

3,通信规则:通过IP地址和端口,我们能将我QQ发送的数据发送到对方QQ上面,但是发送过程中还要满足一个条件,就是我们两个人必须使用相同的通信规则,这个通信规则就称为协议,国际组织定义的通信协议时TCP/IP协议。因为通信协议不止一种,我使用QQ给你发送消息,使用的是A协议,而你接受是通过B协议肯定是行不通的,只有双方遵守相同的协议通信才能成功。

4,IP地址:IP地址是四端数字的排列组合,也就是我们熟知的IPV4地址,每一位的范围是0----255。例如:192.168.1.102。每台主机的IP地址是不一样的,后来为了解决IP地址不够用的问题就出现了IPV6地址,它支持字母和数字的组合,一共有八段。例如:2001:0DB8:0000:0000:0000:0000:1428:0000。我们自己电脑的IP地址可以通过命令行ipconfig命令查看,每台主机的本地回环地址是127.0.0.1,对应主机名是:localhost

二,网络参考模型



OSI的参考模型应用层,表示层,会话层对应TCP/IP参考模型的应用层,数据链路层和物理层对应TCP/IP参考模型的主机至网络层。Web应用程序的开发走的是应用层,而在学习网络编程的过程中我们直接操作的是传输层,关于应用层将在学习web开发时总结。

需求:获取本地IP地址和主机名的方法,以及获取指定网络主机的Ip地址。

import java.net.*;
public class InetAddressDemo
{
public static void main(String[] args) throws Exception {
//获取本地IP地址对象
InetAddress i = InetAddress.getLocalHost();
//获取本地主机名
System.out.println("name:" + i.getHostName());
//获取本地IP地址
System.out.println("address:" + i.getHostAddress());
System.out.println(i.getCanonicalHostName());
//获取网络主机的InetAddress对象,获取百度的IP地址
//InetAddress ie = InetAddress.getByName("www.baidu.com");//通过主机名获取InetAddress对象
InetAddress[] ia = InetAddress.getAllByName("www.baidu.com");
for(InetAddress i2: ia) {
System.out.println("name:" + i2.getHostName());
System.out.println("address:" + i2.getHostAddress());
}
}
}


三,网络通信协议:UDP和TCP

1,UDP通信协议:

(1)将数据及源和目的封装成包,不建立连接:发送方在发送数据的时候,不需要先建立连接,发送方只要将数据打包发送后就不管对方收不收的到了。

(2)数据包的大小有限制,一次只能发送64k,如果包超过64则分多次发送。

(3)面向无连接,所以协议不可靠,发送的数据包可能丢失。

(4)因为建立无连接,所以速度快。(比如聊天发送信息用的就是UDP协议,视屏会议,桌面共享都是UDP传输,就因为速度快)

2,TCP通信协议:

(1)建立连接,形成传输数据的通道:必须先确定对方在才发送数据。

(2)连接中进行大数据的传输。

(3)通过三次握手完成连接,可靠协议。

(4)由于要建立连接,比UDP效率低。(比如下载视频,文件,使用的就是TCP/IP协议)

四,网络通信Socket

Socket是为网络服务提供的一种机制,通信的两端都有Socket,网络通信其实就是Socket通信,数据在两个Socket间是通过IO传输。

1,使用UDP协议发送数据的基本原理:

同时运行下面的两个程序,先启动接收端监听10000端口,然后启动发送端,接收端将接收到发送端的封装的数据。

需求一:通过Udp传输方式,将一段数据发送出去

思路:

(1),建立udpsocket服务

(2),提供数据,并将数据封装到数据包中

(3),通过socket服务的发送功能,将数据发送出去

(4),关闭资源

import java.net.*;
class UdpSend
{
public static void main(String[] args) throws Exception {
//1,创建udp服务,通过Datagramsocket()构造函数;
DatagramSocket ds = new DatagramSocket(9999);
//指定发送端口号9999,那么接收端接收的就是9999端口发送的数据
//2,提供数据并将数据封装到数据包,将数据发送到10000端口
byte[] buf = "shu ju fa song".getBytes();
DatagramPacket dp = new
DatagramPacket(buf,buf.length,InetAddress.getByName("27.19.74.69"),10000);
//3,通过socket服务,将已有的数据包发送出去,通过send方法。send(DatagramPacket p)
ds.send(dp);
//4,关闭资源
ds.close();
}
}


需求二:定义一个程序,用于接收udp传输协议发送的数据,并处理。然后在定义udp接收端

思路:

(1),建立udpsocket服务,通常会监听一个端口,其实就是给这个网络接受程序定义一个数字标示;

方便于明确哪些数据过来该应用程序能够处理。在不定义该标示时,默认是系统分配的。

(2),定义一个数据包,因为要存储接收的字节数组,数据包对象中有根多的功能

能都对数据进行处理,提取字节数据中的不同信息。

(3),通过socket服务的receive方法将收到的数据存储到定义好的数据包中

(4),通过数据包对象的特有功能,将数据包中的字节数据进行提取,打印在控制台上

(5),关闭资源

class UdpRece
{
public static void main(String[] args) throws Exception {
//1,接收方创建udp socket,监听10000端口
DatagramSocket ds = new DatagramSocket(10000);
//2,定义数据包用于存储数据
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//3,通过socket服务的receive方法将收到的数据存储到已经定义好的数据包
ds.receive(dp);
//receive是阻塞式方法,当没有数据时会等待数据
//4,通过数据包的方法获取数据包中的数据
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println(ip + "-----" + "-----" + data + "-----" + port);
//5,关闭资源
ds.close();
}
}


五,UDP通信协议示例
1,需求:通过UDP协议,定义一个接收端和发送端,发送端通过键盘输入字符串,在接受端能够接受这些数据。当发送端输入886时,发送端结束。接收端可以一直监听发送端。

import java.net.*;
import java.io.*;
//建立发送端
class UpdSend2
{
public static void main(String[] args) throws Exception {
DatagramSocket ds = new DatagramSocket();
//接受键盘输入
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line = bufr.readLine())!=null)
{
if("886".equals(line))
break;
byte[] b = line.getBytes();
//将接收到的每行字符串封装成数据包,然后发送到127.0.0.1主机的10001端口
DatagramPacket dp = new DatagramPacket(b,b.length,InetAddress.getByName("127.0.0.1"),10001);
ds.send(dp);
}
ds.close();
}
}
//建立接收端
class UdpReceive
{
public static void main(String[] args)throws Exception {
DatagramSocket ds =new DatagramSocket(10001);//服务只建立一次,端口一旦被使用,其它程序就不能使用
//本地主机的10001端口监听发送过来的数据包
while (true)
{
byte[] b = new byte[1024];
DatagramPacket dp = new DatagramPacket(b,b.length);
ds.receive(dp);//阻塞式方法,没有数据传送进来时会一直等待
//获取对方的IP
String ip = dp.getAddress().getHostAddress();
//getData()获取的是对方数据包的字节数组,要转换成字符串才能打印
String data = new String(dp.getData(),0,dp.getLength());
System.out.println(ip + ":::::::::" + data);
}
}
}


2,需求:使用UDP协议实现一个聊天程序,要求在同一个命令窗口显示发送的信息和接收的信息。

import java.io.*;
import java.net.*;
public class MyChat
{
public static void main(String[] args) throws Exception {
//启动接收线程和发送线程
DatagramSocket sendSocket = new DatagramSocket(10019);
DatagramSocket receiveSocket = new DatagramSocket(10002);
new Thread(new Send(sendSocket)).start();
new Thread(new Receive(receiveSocket)).start();
}
}
//定义发送线程
class Send implements Runnable
{
private DatagramSocket ds;
public Send(DatagramSocket ds) {
this.ds = ds;
}
public void run() {
try
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line = bufr.readLine()) != null)
{
if("886".equals(line))
break;
byte[] b = line.getBytes();
DatagramPacket dp = new
DatagramPacket(b,b.length,InetAddress.getByName("JACK-PC"),10002);
ds.send(dp);
}
ds.close();
}
catch (Exception e)
{
throw new RuntimeException("Send error,please try again");
}

}
}
//定义接受线程
class Receive implements Runnable
{
private DatagramSocket ds;
public Receive(DatagramSocket ds) {
this.ds = ds;
}
public void run() {
try
{
while (true)
{
byte[] b = new byte[1024];
DatagramPacket dp = new DatagramPacket(b,b.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
System.out.println(ip + ":::::::::" + data);
}

}
catch (Exception e)
{
throw new RuntimeException("Get errror");
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐