在计算机网络中,有OSI参考模型和TCP/IP参考模型。TCP/IP是时事上的标准,在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机。常采用TCP和UDP两种网络传输方式。
TCP是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建 立连接,以便在TCP协议的基础上进行通信,当一个socket等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。UDP是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。但是UDP操作简单,而且仅需要较少的资源,因此通常用于对实时性要求高的环境。
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。
一、Socket通讯的过程
Server端Listen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。
对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:
(1) 创建Socket;
(2) 打开连接到Socket的输入/出流;
(3) 按照一定的协议对Socket进行读/写操作;
(4) 关闭Socket,资源进行释放。
二、采用TCP时的通讯过程
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 1创建服务端对象。
ServerSocket ss = new ServerSocket(10002);
// 2,获取连接过来的客户端对象。
Socket s = ss.accept();// 阻塞式.
String ip = s.getInetAddress().getHostAddress();
// 3,通过socket对象获取输入流,要读取客户端发来的数据
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf, 0, len);
System.out.println(ip + ":" + text);
//4, 关闭Socket,资源进行释放
s.close();
ss.close();
}
}
public class ClientDemo {
public static void main(String[] args) throws UnknownHostException,
IOException {
// 1,创建客户端socket服务。
Socket socket = new Socket("192.168.80.1", 8080);
// 2,获取socket流中的输出流。
OutputStream out = socket.getOutputStream();
// 3,使用输出流将指定的数据写出去。
out.write("TCP TEST".getBytes());
// 4,关闭资源。
socket.close();
}
}
三、采用UDP时的通讯过程
public class UDPReceDemo {
public static void main(String[] args) throws IOException {
System.out.println("接收端启动......");
// 1,建立udp socket服务,监听端口号
DatagramSocket ds = new DatagramSocket(10000);
// 2,创建数据包。
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
// 3,使用接收方法将数据存储到数据包中。
ds.receive(dp);// 阻塞式的。
// 4,通过数据包对象的方法,解析其中的数据,比如,地址,端口,数据内容。
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(), 0, dp.getLength());
System.out.println(ip + ":" + port + ":" + text);
// 5,关闭资源。
ds.close();
}
}
public class UDPSendDemo {
public static void main(String[] args) throws IOException {
System.out.println("发送端启动......");
// 1,udpsocket服务。使用DatagramSocket对象。
DatagramSocket ds = new DatagramSocket(3030);
// 2,将要发送的数据封装到数据包中。
String str = "UDP TEST";
// 使用DatagramPacket将数据封装到的该对象包中。
byte[] buf = str.getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length,
InetAddress.getByName("192.168.80.1"), 10000);
// 3,通过udp的socket服务将数据包发送出去。使用send方法。
ds.send(dp);
// 4,关闭资源。
ds.close();
}
}
四、多线程文件并发上传
public class UploadServer {
public static void main(String[] args) throws IOException {
System.out.println("上传服务端。。。。。。。。。");
//1,创建服务
ServerSocket ss = new ServerSocket(10005);
//2,启动Socket
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress()+".....connected");
//3,启动读写操作
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter bufw = new BufferedWriter(new FileWriter("c:\\server.txt"));
String line = null;
while((line=bufIn.readLine())!=null){
bufw.write(line);
bufw.newLine();
bufw.flush();
}
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
out.println("上传成功");
//4,资源释放
bufw.close();
s.close();
ss.close();
}
}
public class UploadClient {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("上传客户端。。。。。。");
File file = new File("c:\\client.txt");
System.out.println(file.exists());
//1,创建服务
Socket s = new Socket("192.168.80.1",10005);
//2,启动读写操作
BufferedReader bufr =
new BufferedReader(new FileReader(file));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
String line = null;
while((line=bufr.readLine())!=null){
out.println(line);
}
s.shutdownOutput();
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str = bufIn.readLine();
System.out.println(str);
//3,资源释放
bufr.close();
s.close();
}
}