udp:(对讲机,不管是否和对方链接成功,都能说话) 无连接 将数据源和目的封装成包 每个数据包的大小限制在64k 不可靠,数据会丢失 速度快 DataGramSocket表示发送端和接受端数据包的套接字,套接字类似插座,港口 模拟聊天窗口 Person1

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

/**
 * 
 * @author WangShuang
 *
 */
public class Person1 {
	public static void main(String[] args) throws SocketException {
		
		Runnable sendDemo = new SendDemo();
		Runnable receiveDemo = new ReceiveDemo();
		new Thread(sendDemo).start();
		new Thread(receiveDemo).start();
	}
}
class SendDemo implements Runnable{
	
	@Override
	public void run() {
		DatagramSocket dgs = null;
		try {
			InetAddress byName = InetAddress.getByName("ip地址");
			//创建udpsocket服务
			dgs = new DatagramSocket();
			//确定方式数据,封装成数据包
			while(true){
				InputStream in = System.in;
				InputStreamReader isr = new InputStreamReader(in);//将字节输入流转成字符输入流
				BufferedReader  br = new BufferedReader(isr);
				String readLine = br.readLine();
				byte[] data = readLine.getBytes();
				DatagramPacket dgp = new DatagramPacket(data, data.length,localHost,10001);
				//通过udpsocket服务的发送功能,将数据包发送
				dgs.send(dgp);
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			dgs.close();
		}
	}
}
class ReceiveDemo implements Runnable{
	
	@Override
	public void run() {
		DatagramSocket dgs = null;
		try {
			//建立udpsocket服务,并未应用程序分配端口
			dgs= new DatagramSocket(10000);
			//建立空数据包,存储接收到的数据,
			byte[] buf = new byte[1024];
			DatagramPacket dgp = new DatagramPacket(buf, buf.length);
			while(true){
				//通过socket服务的接受功能,接收数据
				dgs.receive(dgp);
				//通过数据包的特有功能,将数据进行提取
				String hostAddress = dgp.getAddress().getHostAddress();
				int port = dgp.getPort();
				byte[] data = dgp.getData();
				String string = new String(data,0,dgp.getLength());
				//处理数据
				System.out.println(hostAddress+"..."+port+"..."+string);
			}
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			dgs.close();
		}
	}
}

Person2

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class Person2 {
	public static void main(String[] args) throws SocketException {
		DatagramSocket sendDatagramSocket = new DatagramSocket();
		DatagramSocket receiveDatagramSocket = new DatagramSocket(10001);
		Runnable sendDemo = new SendDemo2(sendDatagramSocket);
		Runnable receiveDemo = new ReceiveDemo2(receiveDatagramSocket);
		new Thread(sendDemo).start();
		new Thread(receiveDemo).start();
	}
}
class SendDemo2 implements Runnable{
	private DatagramSocket dgs;
	public SendDemo2(DatagramSocket dgs) {
		this.dgs = dgs;
	}
	@Override
	public void run() {
		try {
			InetAddress byName = InetAddress.getByName("ip地址");
			//创建udpsocket服务
			//确定方式数据,封装成数据包
			while(true){
				InputStream in = System.in;
				InputStreamReader isr = new InputStreamReader(in);//将字节输入流转成字符输入流
				BufferedReader  br = new BufferedReader(isr);
				String readLine = br.readLine();
				byte[] data = readLine.getBytes();
				DatagramPacket dgp = new DatagramPacket(data, data.length,localHost,10000);
				//通过udpsocket服务的发送功能,将数据包发送
				dgs.send(dgp);
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			dgs.close();
		}
	}
}
class ReceiveDemo2 implements Runnable{
	private DatagramSocket dgs;
	public ReceiveDemo2(DatagramSocket dgs) {
		this.dgs = dgs;
	}
	@Override
	public void run() {
		try {
			//建立udpsocket服务,并未应用程序分配端口
			//建立空数据包,存储接收到的数据,
			byte[] buf = new byte[1024];
			DatagramPacket dgp = new DatagramPacket(buf, buf.length);
			while(true){
				//通过socket服务的接受功能,接收数据
				dgs.receive(dgp);
				//通过数据包的特有功能,将数据进行提取
				String hostAddress = dgp.getAddress().getHostAddress();
				int port = dgp.getPort();
				byte[] data = dgp.getData();
				String string = new String(data,0,dgp.getLength());
				//处理数据
				System.out.println(hostAddress+"..."+port+"..."+string);
			}
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			dgs.close();
		}
	}
}

tcp(电话,只有和对方建立连接才能通话) 建立连接,形成传输数据的通道(socket流) 在链接中,可以进行一次性的大量数据的传输 链接通过3次握手完成的,在吗?在。知道了 数据相对慢 分为客户端(socket)和服务端(ServerSocket) 客户端

 import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

/**
 * 
 * @author WangShuang
 *
 */
public class ClientDemo {
	public static void main(String[] args) throws SocketException {
		Socket socket = null;
		BufferedReader br=null;
		try {
			InetAddress byName = InetAddress.getByName("ip地址");
			
			//创建客户端socket服务,指定目的主机和端口
			 socket = new Socket(byName,9999);
			 
			//为了发送数据,应该获取socket流中的输出流,将数据写到该流中,通过网络发送给服务端
			OutputStream outputStreamsocket = socket.getOutputStream();
			
			//将socket输出流转成字符缓冲输出流
			OutputStreamWriter oswsocket = new OutputStreamWriter(outputStreamsocket);//通过转换流将字节输出流转为字符输出流
			BufferedWriter bwsocket = new BufferedWriter(oswsocket);//字符缓冲流
			
			//读取键盘输入的数据,并转成字符缓冲流
		 br = new BufferedReader(new InputStreamReader(System.in));
			String readLine = null;
			while((readLine=br.readLine())!=null){
				//将键盘输入的数据,写到socket流中
				bwsocket.write(readLine);
				bwsocket.newLine();
				bwsocket.flush();
				
				//获取socket输入流,将服务端的数据获取到,并打印
				BufferedReader fbrsocket = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				System.out.println("服务端返回的数据"+fbrsocket.readLine());
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
			br.close()
				//关闭客户端资源
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

服务端

 import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ServiceDemo {
	public static void main(String[] args) {
		//创建服务端socket服务
		ServerSocket serverSocket=null;
		Socket socket =null;
		try {
			serverSocket = new ServerSocket(9999);
			//获取客户端socket对象
			socket = serverSocket.accept();
			
			//获取socket输入流,并转成字符缓冲输入流,将客户端的数据读取到,并打印
			InputStream stream = socket.getInputStream();
			BufferedReader brsocket = new BufferedReader(new InputStreamReader(stream)) ;
			String data = null;
			while((data=brsocket.readLine())!=null){
				System.out.println("客户端发送的数据"+data);
				
				//反馈信息给客户端
				BufferedWriter bwsockect = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())) ;
				bwsockect.write(data.toUpperCase());
				bwsockect.newLine();
				bwsockect.flush();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

问题:为什么客户端关闭以后,服务端也关闭呢 因为客户端的socket已经关闭了,服务端是获取的客户端的socket,所以服务端也技术了

如果发生客户端和服务端程序都停止运行,那么就应该从readLine()方法入手,因为该方法是阻塞式方法,像缓冲区中写数据时是否刷新,是否有结束