TCP(transmission control protocol):
是专门设计用在与不可靠的因特网上提供可靠的,端到端的字节流通信的协议。它是一种面向连接的协议。TCP连接是字节流而非报文流。
两个Java应用程序可通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个socket。
socket通常用来实现client-server连接。
java.net包中定义的两个类socket和ServerSocket,分别用来实现双向连接的client和server端。
建立连接时所需的寻址信息为远程计算机的IP地址和端口号(port number)。
服务器用ServerSocket和Socket。
ServerSocket是阻塞式的服务。
Sever端的端口号要指定,一共有65536个端口,不要用0-1024。
TCP和UDP端口独立,不会互相冲突。
必须用serverSocket.accept方法来接受一个连接。
程序开发的时候,是server和client一起开发。
而程序运行的时候,先启动server,再启动client。
服务器程序编写:
①调用ServerSocket(int port)创建一个服务器端套接字,并绑定到指定端口上;②调用accept(),监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字。③调用Socket类的getOutputStream()和getInputStream获取输出流和输入流,开始网络数据的发送和接收。④最后关闭通信套接字。
import java.net.*;
import java.io.*;
publicclass TCPServer {
publicstaticvoid main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(6666);
while(true) {
Socket s =ss.accept(); 用accept方法来接受来自客户端的连接。
System.out.println("a client connect!");
DataInputStream dis = new DataInputStream(s.getInputStream());
System.out.println(dis.readUTF());
dis.close();
s.close();
}
}
}
客户机用Socket,在构造方法里面填的信息是服务器的IP地址和端口号,client自己这边的端口由系统指定。其实我们编程的时候是不知道哪个端口出去的。
客户端程序编写:
①调用Socket()创建一个流套接字,并连接到服务器端;②调用Socket类的getOutputStream()和getInputStream获取输出流和输入流,开始网络数据的发送和接收。③最后关闭通信套接字。
import java.net.*;
import java.io.*;
publicclass TCPClient {
publicstaticvoid main(String[] args) throws Exception {
Socket s = new Socket("127.0.0.1", 6666);
OutputStream os = s.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
Thread.sleep(30000);
dos.writeUTF("helloserver!");
dos.flush();
dos.close();
s.close();
}
}
UDP(user data protocol):UDP向应用程序提供了一种发送封装的原始IP数据报的方法,并且发送时无需建立连接。是一种不可靠的连接。
关键字:不可靠的,效率高,用的是数据报,非连接、
其实对UDP而言,不区分SeverSocket和Socket,也没有server和client的概念。只有逻辑上的服务器和客户机。
服务器端
import java.net.*;
import java.io.*;
publicclass TestUDPServer
{
publicstaticvoid main(String args[]) throws Exception
{
byte buf[] = newbyte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
DatagramSocket ds = new DatagramSocket(5678);
while(true)
{
ds.receive(dp);
ByteArrayInputStream bais = new ByteArrayInputStream(buf);
DataInputStream dis = new DataInputStream(bais);
System.out.println(dis.readLong());
}
}
}
客户机:
import java.net.*;
import java.io.*;
publicclass TestUDPClient
{
publicstaticvoid main(String args[]) throws Exception
{
long n = 10000L;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeLong(n);
byte[] buf = baos.toByteArray();
System.out.println(buf.length);
DatagramPacket dp = new DatagramPacket(buf, buf.length,
newInetSocketAddress("127.0.0.1",5678) //是一个ScocketAddress
);
DatagramSocket ds = new DatagramSocket(9999);
ds.send(dp);
ds.close();
}
}
接收端程序编写:
①调用DatagramSocket(int port)创建一个数据报套接字,并绑定到指定端口上;②调用DatagramPacket(byte[] buf, int length),建立一个字节数组以接收UDP包。③调用DatagramSocket类的receive(),接收UDP包。④最后关闭数据报套接字。
发送端程序编写:
①调用DatagramSocket()创建一个数据报套接字;②调用DatagramPacket(byte[] buf, int offset, int length, InetAddressaddress, int port),建立要发送的UDP包。③调用DatagramSocket类的send(),发送UDP包。④最后关闭数据报套接字。