网络编程回顾:
网络传输三要素:
1、通过IP地址找到对方。
2、指定数据要传输到的应用程序的所属端口。
3、定义通讯规则,这个规则称为协议(TCP/IP)
常见协议:UDP、TCP。
UDP和TCP特点:
UDP:
1、面向无连接,将数据及源和目的封装成数据报包。
2、每个数据报包大小限制在64k内。
3、以为面向无连接,所以是不可靠协议。
4、因为面向无连接,所以传输速度较快。
(凌波、视频会议等等)
TCP:
1、面向连接,形成传输的通道。
2、在连接中进行大数据量的数据传输。
3、通过三次握手完成连接,是可靠协议。
三次握手:(A:你在吗? B:我在。 A:我知道你在了。)
4、因为必须要建立连接,效率会稍低。
(文件的上传、下载)
Socket:
是实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。
Socket就是为网络服务提供的一种机制,通讯两端都要有Socket。
网络通信就是Socket间的通信,数据在两个Socket间通过IO技术进行数据传输。
利用UDP实现的聊天小程序。
import java.io.*;
import java.net.*;
class Send implements Runnable
{
//定义DatagramSocket局部变量,便于Send初始化。
private DatagramSocket ds ;
//定义一个构造函数,对Send进行初始化。
public Send(DatagramSocket ds )
{
this.ds = ds;
}
//复写run()方法。
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[] buf = line.getBytes();
//创建DatagramPacket对象并指定IP和端口,并将缓冲区内容打包
DatagramPacket dp =
new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),8888);
//用DatagramSocket的send()方法将数据报包发送出去。
ds.send(dp);
}
ds.close();
}
catch (Exception e)
{
throw new RuntimeException("发送失败");
}
}
}
class Rece implements Runnable
{
private DatagramSocket ds ;
public Rece(DatagramSocket ds )
{
this.ds = ds;
}
public void run()
{
try
{
while(true)
{
//定义一个长度为1024的缓冲区
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
//获取IP地址,
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("接收失败");
}
}
}
class ChatDemo
{
public static void main(String[] args) throws Exception
{
//创建Send 和 Rece 的DatagramSocket对象,并指定监听的端口。
DatagramSocket senfDs = new DatagramSocket(6666);
DatagramSocket receDs = new DatagramSocket(8888);
//开启线程,进行通讯。
new Thread(new Send(senfDs)).start();
new Thread(new Rece(receDs)).start();
}
}
利用TCP实现的图片上传小程序。
import java.net.*;
import java.io.*;
class UploadClient
{
public static void main(String[] args) throws Exception
{
//建立服务端点
Socket s = new Socket("127.0.0.1",10086);
//读取图片文件
FileInputStream fis = new FileInputStream("D:\\1.jpg");
//通过Socket输出流将数据发送给服务端。
OutputStream socOut = s.getOutputStream();
//定义一个缓冲区
byte[] buf = new byte[1024];
int len = -1;
//开始读取并发出数据。
while((len=fis.read(buf))!=-1)
{
socOut.write(buf,0,len);
}
//定义结束标记,标识文件已写完
s.shutdownOutput();
//定义一个读取流读取服务端的反馈信息。
InputStream socIn = s.getInputStream();
//定义一个缓冲区,用来临时存储数据
byte[] bufIn = new byte[1024];
int num = socIn.read(bufIn);
String data = new String(bufIn,0,num);
System.out.println("服务端反馈信息:"+data);
fis.close();
s.close();
}
}
class UploadServer
{
public static void main(String[] args) throws Exception
{
//建立服务端点
ServerSocket ss = new ServerSocket(10086);
//获取客户端对象。
Socket s = ss.accept();
//获取客户端IP地址,并打印
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip + "已成功链接");
//获取客户端对象的读取流对象,读取客户端发来的数据。
InputStream socIn = s.getInputStream();
//定义一个文件写入流将接受的数据进行存储。
FileOutputStream fos = new FileOutputStream("girl.jpg");
//定义一个缓冲区,对数据进行临时存储。
byte[] buf = new byte[1024];
//开始读写数据
int len = -1;
while((len=socIn.read(buf))!=-1)
{
fos.write(buf,0,len);
}
System.out.println("图片已储存");
//获取客户端对象的文件输出流,给客户端发送反馈信息
OutputStream socOut = s.getOutputStream();
socOut.write("恭喜您!图片上传成功!".getBytes());
fos.close();
s.close();
ss.close();
}
}
//127.0.0.1已成功链接
//图片已储存
//服务端反馈信息:恭喜您!图片上传成功!