我们知道java中的TCP编程,UDP编程,TCP面向连接,UDP面向无连接。
Socket
1、Socket可以说是对网络的一种抽象,通过它可以对网络中的数据进行读写,根据TCP协议和UDP协议的不同,在网络编程方面就有面向两个协议的不同socket,一个是面向字节流的一个是面向报文的。
2、应用通过socket通信,肯定就有一个服务器端和一个客户端。所以它必然就包含有一个对应的IP地址。另外,在这个地址上server要提供一系列的服务,于是就需要有一系列对应的窗口来提供服务。所以就有一个对应的端口号(Port)。端口号是一个16位的二进制数字,那么范围就是从(0-65535)。IP地址加端口号基本上就构成了socket。
TCP:
TCP:面向连接传输数据的协议
Server
Server服务器端要做的工作就是建立一个通信的端点,等待客户端的访问,典型的处理步骤如下:
1、先建立一个ServerSocket服务器端socket,并为其指定端口号。这个socket就是用来监听指定端口的连接请求的。
2、然后在使用accept获得客户端的请求,通过accept()方法返回的socket实例,建立了一个和客户端的新连接。
3、通过这个socket实例获得其OutputStream 、InputStream,对Socket进行读写操作。
4、结束的时候调用close方法关闭socket
参考案例:完成客户端向服务器端上传文件,服务器端接收文件
package com.xiaohong.tcptest;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created Learn_Tcp_File.
* By XIAOHONG .
* On 2016/8/17.
*/
public class Server {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(10000);
Socket socket;
while ((socket = server.accept()) != null) {
// 因为不知道是什么类型的文件
DataInputStream dis = new DataInputStream(socket.getInputStream());
// 文件名
String name = dis.readUTF();
// 文件长度
long file_length = dis.readLong();
// 文件
FileOutputStream fos = new FileOutputStream("C:" + File.separator + "temp" +File.separator +name);
byte[] buffer = new byte[102400];
int length;
while (file_length > 0) {
length = dis.read(buffer, 0, (int) Math.min(buffer.length,file_length));
file_length -= length;
fos.write(buffer,0, length);
}
dis.close();
fos.close();
socket.close();
System.out.println("接受成功");
/* byte[] buffer = new byte[((int) file_length)];
// 大文件会溢出,大文件要随读随写
dis.readFully(buffer);*/
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client
客户端的操作过程:
1、首先建立Socket对象,用于向服务器传递数据,通过指定的远程服务器地址和端口来建立连接。
2、通过Socket实例包含的InputStream和OutputStream来进行数据的读写。
3、操作结束后调用socket实例的close方法,关闭。
代码:
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 10000);
File file = new File("C:" + File.separator + "temp1" + File.separator + "b.txt");
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(file.getName());
dos.writeLong(file.length());
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[102400];
int length;
while ((length = fis.read(buffer)) != -1) {
dos.write(buffer, 0 ,length);
}
System.out.println("上传完毕");
dos.close();
fis.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
UDP:面向无连接传输数据的协议
UDP协议在传输数据时,不需要建立连接,只要获得服务器的IP,便可王服务器发送东西,也不管消息最终会到达什么地方
Server
UDP协议中的Server端,一般的操作步骤:
1、首先建立DatagramSocket实例,并指定端口号。用于指明发送站。
2、再建立一个DatagramPacket实例,用于存储通信的内容。
3、 通过DatagramSocket实例的receive方法接收DatagramPacket.DatagramPacket中间就包含了通信的内容。
4、 通过DatagramSocket的send和receive方法来收和发DatagramPacket.
public static void main(String[] args) {
try {
// DatagramPacket表示存放数据的数据报,DatagramSocket表示接受或发送数据报的套接字,即发送站或接收站
DatagramSocket socket = new DatagramSocket(10000);
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
System.out.println("等待客户端连接");
System.out.println("dsf");
// 阻塞进程,知道读到客户端发来的packet为止
socket.receive(packet);
System.out.println("f");
System.out.println(packet.getAddress().getHostAddress());
System.out.println(packet.getPort());
System.out.println(new String(packet.getData(), packet.getOffset(), packet.getLength()));
byte[] buffer = "呵呵呵呵呵呵呵哒哒".getBytes("UTF-8");
packet.setData(buffer);
socket.send(packet);
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Client
UDP协议中的客户端
1、同服务器端一样,构造DatagramSocket实例。
2.通过DatagramSocket实例的send和receive方法发送DatagramPacket报文。
3.结束后,调用DatagramSocket的close方法关闭。
4、InetAddress的使用http://www.cnblogs.com/hnrainll/archive/2012/01/09/2317515.html
public static void main(String[] args) {
try {
InetAddress host = InetAddress.getByName("localhost");
System.out.println(host.getHostAddress());
// 如果Ip中大于128的话,会表述为一个负数
System.out.println(Arrays.toString(host.getAddress()));
DatagramSocket socket = new DatagramSocket();
byte[] data = "客户端发来的数据".getBytes("UTF-8");
DatagramPacket packet = new DatagramPacket(data, data.length);
packet.setAddress(host);
packet.setPort(10000);
socket.send(packet);
socket.receive(packet);
System.out.println("发送完成");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}