关于如何实现UDP和TCP连接(具体应用),下面给出了几个例子
客户端代码
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class UdpProducer {
public static void main(String[] args) throws Exception {
//建立套接字接口
@SuppressWarnings("resource")
DatagramSocket socket = new DatagramSocket();
InetAddress address = InetAddress.getByName("localhost");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //实例化Scanner类
String line;
while((line = br.readLine())!=null){
//发送的数据报包
DatagramPacket datagramPacket = new DatagramPacket(line.getBytes(),line.getBytes().length,address,8080);
socket.send(datagramPacket);
}
}
}
客户端主动访问服务端,所以需要加上ip地址,这里访问本机使用localhost.
服务端代码
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class UdpConsumer {
public static void main(String[] args) throws Exception {
@SuppressWarnings("resource")
DatagramSocket datagramSocket = new DatagramSocket(8080);//绑定消息接收端口8080
// 用以存放接收数据的字节数组
byte[] msgByte = new byte[1024];
// 接收消息的数据报包
DatagramPacket packet = new DatagramPacket(msgByte, msgByte.length);
@SuppressWarnings({ "resource"})
Scanner sc = new Scanner(System.in); //实例化Scanner类
while(true){
datagramSocket.receive(packet);
String msg = new String(packet.getData(),0,packet.getLength());
System.out.println("窗口B收到信息:"+msg);
}
}
}
服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求,这里监听8080端口.
与UDP不同之处在于,TCP连接需要通过三次握手.
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
这三次握手都不会携带任何待传送的数据.
客户端代码
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class TcpProducer {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost",8010);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
OutputStream os = socket.getOutputStream();
String line;
while((line = br.readLine())!=null){
os.write( line.getBytes());
os.flush();
}
}
}
同样的,客户端需要主动访问服务端的ip'地址和端口号
服务端代码
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpConsumer {
public static void main(String[] args) throws Exception {
@SuppressWarnings("resource")
ServerSocket serverSocket = new ServerSocket(8010);//监听8010端口
Socket accept = serverSocket.accept();//阻塞方法,等待发送端的链接请求
while(true){
// 获取连接对象的输入流
InputStream in = accept.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
}
}
}
UDP和TCP连接的不同点:
1.TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接.如上面的代码如果先启动UDP的客户端是不会报错的,而先启动TCP的客户端就会报错"connection refused"(连接被拒绝!);
2.TCP提供可靠的服务,更具准确性.相对而言UDP只管数据发送出去了,其它东西什么都不管.
3.UDP具有广播性,支持一对多发送;TCP是点对点协议;
4.UDP连接响应速度快,时效性更高,TCP连接需要经过多次握手;
下面是一个基于UDP连接的聊天小程序服务端代码;
窗口A与窗口B
public class WindowA {
private static final int SEND_PORT = 8090;//向哪个端口发送信息
private static final int RECEIVE_PORT = 8080;//绑定一个端口接收信息
public static void main(String[] args) {
System.out.println("开始聊天啦!");
new Thread(new ReceiveListener(RECEIVE_PORT)).start();
new Thread(new SendListener(SEND_PORT,"小红")).start();
}
}
public class WindowB {
private static final int SEND_PORT = 8080;//向哪个端口发送信息
private static final int RECEIVE_PORT = 8090;//绑定一个端口接收信息
public static void main(String[] args) {
System.out.println("开始聊天啦!");
new Thread(new ReceiveListener(RECEIVE_PORT)).start();
new Thread(new SendListener(SEND_PORT,"小明")).start();
}
}
接收监听:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Scanner;
public class ReceiveListener implements Runnable {
private int port;
ReceiveListener(int port){
this.port = port;
}
@Override
public void run() {
try{
@SuppressWarnings("resource")
DatagramSocket datagramSocket = new DatagramSocket(port);//绑定消息接收端口8080
// 用以存放接收数据的字节数组
byte[] msgByte = new byte[1024];
// 接收消息的数据报包
DatagramPacket packet = new DatagramPacket(msgByte, msgByte.length);
while(true){
datagramSocket.receive(packet);
String msg = new String(packet.getData(),0,packet.getLength());
System.out.println(msg);
}
}catch(Exception e){
System.out.println("出错了!出错信息:"+e.getMessage());
}
}
}
发送监听:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SendListener implements Runnable {
private int port;
private String name;
private static SimpleDateFormat format;
{
format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
SendListener(int port,String name){
this.port = port;
this.name = name;
}
@Override
public void run() {
try{
@SuppressWarnings("resource")
DatagramSocket socket = new DatagramSocket();
InetAddress address = InetAddress.getByName("localhost");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //实例化Scanner类
String line;
while((line = br.readLine())!=null){
//发送的数据报包
line = name +":"+line+" "+format.format(new Date());
DatagramPacket datagramPacket = new DatagramPacket(line.getBytes(),line.getBytes().length,address,port);
socket.send(datagramPacket);
}
}catch(Exception e){
System.out.println("出错了!出错信息:"+e.getMessage());
}
}
}
运行结果:
窗口B:
窗口A:
就是这样的!喵~如果你想知道更多关于TCP和UDP的知识,请点击这里Http和Socket 优劣比较
好了!掰掰!