---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
这部分的主要知识点:
1.网络编程概述;
2.UDP传输;
3.TCP传输。
一、网络编程概述
1.网络参考模型
OSI参考模型:包括应用层、表示层、会话层、传输层、网络层、数据链路层、物理层七层。
TCP/IP参考模型:包括应用层(对应OSI模型的应用层、表示层和会话层)、传输层(对应OSI模型的传输层)、网际层(对应OSI模型的网络层)、主机至网络层(对应OSI模型的数据链路层和物理层)四层。
2.网络通讯要素
(1)IP地址
IP地址是网络中设备的标识。本地回环地址为127.0.0.1,主机名为localhost。192.168.1.0表示网络段,192.168.1.255表示这个网络段上的广播地址。
表示IP地址的类是InetAddress。
import java.net.*;
class IPDemo
{
public static void main(String[] args) throws UnknownHostException
{
InetAddress i = InetAddress.getLocalHost();//获得本地主机
System.out.println(i);
System.out.println(i.getHostName());//获取IP地址的主机名
System.out.println(i.getHostAddress());//获取IP地址的字符串表现形式
//在给定主机名的情况下确定主机的IP地址
InetAddress ia = InetAddress.getByName("www.baidu.com");
System.out.println(ia.getHostName());
System.out.println(ia.getHostAddress());
//在给定主机名的情况下,获取其IP地址组成的数组
InetAddress[] ias = InetAddress.getAllByName("www.taobao.com");
for(InetAddress add:ias)
System.out.println(add.getHostAddress());
}
}
(2)端口号
端口用于标识进程的逻辑地址。有效端口号是0~65535,其实0~1024为系统使用或保留端口。
(3)传输协议
传输协议表示通讯的规则,常用的协议有UDP和TCP。
3.TCP和UDP
(1)UDP
将数据封装在数据报中;每个数据报的大小限制在64k内;面向无连接,不可靠;传输速度快。
(2)TCP
建立连接,形成传输数据的通道;传输数据量大;连接要“三次握手”,可靠;效率稍低,速度慢。
4.socket(套接字)
socket是为网络服务提供的一种机制,网络通信的两端都有socket,网络通信其实就是socket之间的通信,数据在两个socket之间通过IO传输。
二、UDP传输
两个对象,DatagramPacket表示数据报包,DatagramSocket表示用来发送和接收数据报包的套接字。
传输过程:使用DatagramSocket建立发送端和接收端;使用DatagramPacket建立数据包;调用DatagramSocket的发送接收方法;关闭DatagramSocket对象。
1.UDP传送数据演示
需求:通过UDP传输方式,将一段文字数据发送出去,并在接收端处理数据。
需要建立一个发送端和一个接收端。
import java.net.*;
/*
UDP发送端建立思路:
1.建立UDPSocket服务;
2.将数据封装到数据包中;
3.通过socket服务的发送功能,将数据包发送出去;
4.关闭资源。
*/
class UdpSend
{
public static void main(String[] args) throws Exception
{
//通过DatagramSocket对象建立socket服务
DatagramSocket ds = new DatagramSocket();
//获取数据,并通过DatagramPacket对象将数据封装成数据包
byte[] buf = "udp ge men lai le".getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.31.1"),10000);
//通过DatagramSocket对象的send方法,将封装好的数据包发送出去
ds.send(dp);
//关闭资源
ds.close();
}
}
/*
UDP接收端建立思路:
1.建立socket服务,监听一个端口;
2.建立一个数据包,用来存储接收到的数据;
3.将接收到的数据存入建立好的数据包中;
4.处理数据;
5.关闭资源。
*/
class UdpReceive
{
public static void main(String[] args) throws Exception
{
//通过DatagramSocket对象建立socket服务,监听10000端口
DatagramSocket ds = new DatagramSocket(10000);
//通过DatagramPacket对象建立数据包
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//通过DatagramSocket对象的receive方法接收数据,并存入建立好的数据包中
ds.receive(dp);
//通过DatagramPacket对象处理获取到的数据
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String data = new String(dp.getData(),0,dp.getLength());
System.out.println(ip+":"+port+"-->"+data);
//关闭资源
ds.close();
}
}
2.通过UDP将键盘录入的数据发送出去
import java.net.*;
import java.io.*;
class UdpSend2
{
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)
{
//如果输入的是"over",则停止输入
if("over".equals(line))
break;
//通过DatagramPacket建立数据包,并发送出去
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.31.1"),10000);
ds.send(dp);
}
bufr.close();
ds.close();
}
}
class UdpRec2
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds = new DatagramSocket(10000);
while(true)//不停的接收
{
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);//阻塞式方法
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String data = new String(dp.getData(),0,dp.getLength());
System.out.println(ip+":"+port+"-->"+data);
}
}
}
3.UDP聊天
需求:编写一个聊天程序。
分析:需要有发数据的部分和收数据的部分,这两部分需要同时进行,所以需要用到多线程,一个线程控制发数据,另一个控制收数据。
import java.net.*;
import java.io.*;
class Send implements Runnable
{
private DatagramSocket ds;
Send(DatagramSocket ds)
{
this.ds = ds;
}
public void run()
{
BufferedReader bufr = null;
try
{
bufr = new BufferedReader(
new InputStreamReader(System.in));
String line = null;
while((line=bufr.readLine())!=null)
{
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.31.1"),10001);
this.ds.send(dp);
if("bb".equals(line))
break;
}
}
catch (Exception e)
{
throw new RuntimeException("发送信息异常");
}
finally
{
if(bufr!=null)
try
{
bufr.close();
}
catch (IOException e)
{
throw new RuntimeException("读取流关闭异常");
}
this.ds.close();
}
}
}
class Rec implements Runnable
{
private DatagramSocket ds;
Rec(DatagramSocket ds)
{
this.ds = ds;
}
public void run()
{
try
{
while(true)
{
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
this.ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
int pt = dp.getPort();
String data = new String(dp.getData(),0,dp.getLength());
if("bb".equals(data))
break;
System.out.println(ip+"("+pt+")"+":::"+data);
}
}
catch(IOException e)
{
e.printStackTrace();
throw new RuntimeException("接收信息异常");
}
finally
{
this.ds.close();
}
}
}
class ChatDemo
{
public static void main(String[] args) throws SocketException
{
DatagramSocket sendSocket = new DatagramSocket();
DatagramSocket recSocket = new DatagramSocket(10001);
new Thread(new Send(sendSocket)).start();
new Thread(new Rec(recSocket)).start();
}
}
三、TCP传输
两个对象,Socket对象表示客户端套接字,ServerSocket对象表示服务器套接字。
传输过程:通过Socket对象建立客户端,ServerSocket对象建立服务端;建立连接受,通过Socket中的IO流进行数据传输;关闭Socket。
1.TCP传输数据演示
import java.io.*;
import java.net.*;
class TcpClient
{
public static void main(String[] args) throws Exception
{
//创建socket服务,并指定要连接的主机和端口
Socket s = new Socket("192.168.31.1",10003);
//从socket中获取字节输出流
OutputStream out = s.getOutputStream();
//将数据写出去
out.write("tcp传送数据".getBytes());
//关闭资源
s.close();
}
}
class TcpServer
{
public static void main(String[] args) throws Exception
{
//建立服务端的socket服务,监听一个端口
ServerSocket ss = new ServerSocket(10003);
//获取连接过来的客户端对象,阻塞式方法
Socket s = ss.accept();
//通过获取的客户端对象,获取数据
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+" connected...");
byte[] buf = new byte[1024];
InputStream in = s.getInputStream();
int len = in.read(buf);
System.out.println(new String(buf,0,len));
//关闭资源
s.close();
ss.close();//可选
}
}
2.服务端反馈信息到客户端
需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息。
import java.io.*;
import java.net.*;
class TcpClient2
{
public static void main(String[] args) throws Exception
{
//建立客户端socket服务,指定连接的主机和端口
Socket s = new Socket("192.168.31.1",10004);
//获取socket的输出流,向服务端发送数据
OutputStream out = s.getOutputStream();
out.write("服务端你好!".getBytes());
//获取socket的输入流,读取服务端的反馈数据
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
//关闭资源
s.close();
}
}
class TcpServer2
{
public static void main(String[] args) throws Exception
{
//建立服务端socket服务,监听端口
ServerSocket ss = new ServerSocket(10004);
//获取链接过来的客户端对象
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+" connected...");
//获取socket的输入流,读取传送过来的数据
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
//获取socket的输出流,向客户端反馈数据
OutputStream out = s.getOutputStream();
out.write("客户端哥们你好,我收到了!".getBytes());
s.close();
ss.close();
}
}
3.TCP练习
需求:建立一个文本转换服务器。客户端给服务端发送文本,服务端将文本转换成大写再发送回客户端。可以不断地进行转换,直到客户端输入"over",转换结束。
因为操作的是文本数据,所以考虑使用字符流,并加入缓冲。
import java.io.*;
import java.net.*;
class TransTextClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("192.168.31.1",10005);
BufferedReader bufr = new BufferedReader(
new InputStreamReader(System.in));
//BufferedWriter bufOut = new BufferedWriter(
// new OutputStreamWriter(s.getOutputStream()));
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
BufferedReader bufIn = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bufr.readLine())!=null)//读取一行数据
{
if("over".equals(line))
break;
//out.write(line.getBytes());
//bufOut.write(line);
//bufOut.newLine();
//bufOut.flush();
pw.println(line);//将一行数据发送到服务端
//从服务端获取返回的数据
String str = bufIn.readLine();
System.out.println("server:"+str);
}
s.close();
bufr.close();
}
}
class TransTextServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10005);
while(true)//服务端不关闭
{
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+" connected...");
BufferedReader bufIn = new BufferedReader(
new InputStreamReader(s.getInputStream()));
//BufferedWriter bufOut = new BufferedWriter(
// new OutputStreamWriter(s.getOutputStream()));
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
//读取客户端发送过来的数据
String line = null;
while((line=bufIn.readLine())!=null)
{
System.out.println(line);
//out.write(data.toUpperCase().getBytes());
//bufOut.write(line.toUpperCase());
//bufOut.newLine();
//bufOut.flush();
pw.println(line.toUpperCase());//将数据转成大写,并发回客户端
}
s.close();
System.out.println(ip+" disconnected...");
}
}
}
4.TCP复制文件
import java.io.*;
import java.net.*;
class UploadTextClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("192.168.31.1",10007);
//System.out.println("nimei");
BufferedReader bufr = new BufferedReader(
new FileReader("client.txt"));
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
String line = null;
while((line=bufr.readLine())!=null)
{
pw.println(line);
}
/*
关闭客户端的输出流,相当于在流中加入一个结束标记-1
否则服务端的读取流读不到结束标记而一直处于等待,
客户端读不到服务端的返回数据也一直处于等待。
*/
s.shutdownOutput();
BufferedReader bufIn = new BufferedReader(
new InputStreamReader(s.getInputStream()));
System.out.println(bufIn.readLine());
bufr.close();
s.close();
}
}
class UploadTextServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10007);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+" connected...");
BufferedReader bufIn = new BufferedReader(
new InputStreamReader(s.getInputStream()));
PrintWriter pw = new PrintWriter(new FileWriter("server.txt"),true);
String line = null;
while((line=bufIn.readLine())!=null)
{
pw.println(line);
}
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
out.println("上传成功");
pw.close();
s.close();
ss.close();
}
}
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net