Tcp与Udp发送消息
TCP 建立连接三次握手;断开连接 四次挥手
类似于打电话,需要对方同意接通,才能通话
- 传输文本
(1)客户端
package tcp.demo1;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class TcpClient {
public static void main(String[] args) {
Socket socket=null;
OutputStream os=null;
try {
//1.要知道服务端插槽,知道服务端端口号
InetAddress serverIp = InetAddress.getByName("127.0.0.1");
int port=999;
//2.创建一个socket连接 连接需要服务端IP地址和服务端端口号
socket = new Socket(serverIp,port);
//3.发送消息 IO流
os =socket.getOutputStream();
os.write("你好".getBytes());//数组
} catch (Exception e) {
e.printStackTrace();
}finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
(2)服务端
package tcp.demo1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) {
ByteArrayOutputStream baos=null;
InputStream is=null;
Socket socket=null;
ServerSocket serverSocket=null;
//1.我得有一个地址
try {
//开启客户端插槽
serverSocket = new ServerSocket(999);
//2.等待客户端连接进来
while(true){
socket=serverSocket.accept();
//3.读取客户端的消息----与客户端消息对应
is=socket.getInputStream();
/*有个弊端 如果传输信息超过1024,会乱码
byte[] buffer=new byte[1024];//建一个数组管道
int len;用len接收消息
while((len=is.read(buffer))!=-1){//说明管道有值
String msg=new String(buffer,0,len);
System.out.println(msg); }*/
//管道流
baos=new ByteArrayOutputStream();
byte[] buffer=new byte[1024];//管道大小
int len;//用len接收消息
while((len=is.read(buffer))!=-1) {
//说明管道有值
baos.write(buffer,0,len);//读进来,写出去
}
System.out.println(baos.toString());}
} catch (IOException e) {
e.printStackTrace();
}
finally {
//关闭资源 先开后关;
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- 传输文件
(1)客户端
package tcp.demo2;
import org.omg.PortableInterceptor.INACTIVE;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class TcpClientfile {
public static void main(String[] args) throws Exception {
//1.创建一个Socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),999);
//2.创建输出流
OutputStream os=socket.getOutputStream();
//3.文件流读取
FileInputStream fis = new FileInputStream(new File("my.png"));
//4.写出文件
byte[] buffer=new byte[1024];//管道大小
int len;//用len接收消息
while((len=fis.read(buffer))!=-1) {
//说明管道有值
os.write(buffer,0,len);//读进来,写出去
}
//通知服务器,我已经结束
socket.shutdownOutput();
//确定服务端接收完毕
InputStream inputStream=socket.getInputStream();
//String byte[]
ByteArrayOutputStream bos=new ByteArrayOutputStream();
byte[] buffer1=new byte[2014];//管道大小
int len1;//用len接收消息
while((len1=inputStream.read(buffer1))!=-1) {
//说明管道有值
bos.write(buffer1,0,len1);//读进来,写出去
}
System.out.println(bos.toString());
//5.关闭资源
bos.close();
inputStream.close();
fis.close();
os.close();
socket.close();
}
}
(2)服务端
package tcp.demo2;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServerfile {
public static void main(String[] args) throws IOException {
//1.创建服务
ServerSocket serverSocket=new ServerSocket(999);
//2.监听客户端连接,阻塞式监听
Socket socket=serverSocket.accept();
//3.获取输入流
InputStream is=socket.getInputStream();
//4.文件输出
FileOutputStream fos=new FileOutputStream(new File("recive.png"));
byte[] buffer=new byte[1024];//管道大小
int len;//用len接收消息
while((len=is.read(buffer))!=-1) {
//说明管道有值
fos.write(buffer,0,len);//读进来,写出去
}
//确定客户端输出完毕
OutputStream ops=socket.getOutputStream();
ops.write("接受完毕".getBytes());
//关闭资源
ops.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
UDP 连接不用对方同意 需要知道对方已经开的端口即可
类似于发短信 不用对方同意 知道对方联系方式就可以
(1)发送端
package udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class Udpsend {
//发送端
public static void main(String[] args) throws Exception {
//1.建立socket连接 相当于连接管道
DatagramSocket socket = new DatagramSocket();
//2.建立包
InetAddress address=InetAddress.getByName("localhost");
String data="Hello word";
int port=9090;
//第一个参数(内容);第二三个参数(从哪开始,到哪结束);第四个参数(地址);第五个参数(端口号)
DatagramPacket datagramPacket = new DatagramPacket(data.getBytes(), 0, data.getBytes().length, address, port);
//3.发送包
socket.send(datagramPacket);
//4.关闭资源
socket.close();
}
}
(2)接收端
package udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Udpreceive {
//接收端
public static void main(String[] args) throws Exception {
//1.开放端口
DatagramSocket socket = new DatagramSocket(9090);
//2.接受数据包
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
socket.receive(packet);//阻塞接收
//3.可以输出看一下
System.out.println(packet.getAddress().getHostAddress());
System.out.println(new String(packet.getData(),0,packet.getLength()));
//4.关闭连接
socket.close();
}
}
多线程聊天
(1)发送端
package chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class Udpchatse implements Runnable{
DatagramSocket socket=null;
BufferedReader reader=null;
private int fromport;
private String tpIp;
private int toport;
public Udpchatse(int fromport, String tpIp, int toport) {
this.fromport = fromport;
this.tpIp = tpIp;
this.toport = toport;
try {
socket = new DatagramSocket(fromport);
} catch (SocketException e) {
e.printStackTrace();
}
reader = new BufferedReader(new InputStreamReader(System.in));
}
@Override
public void run() {
//准备数据,从控制台输入
while (true){
try {
String data=reader.readLine();//读取数据
byte[] bytes = data.getBytes();//转换
//打包
DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length, new InetSocketAddress(tpIp,toport));
//发送
socket.send(packet);
if(data.trim().equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
(2)接收端
package chat;
import sun.awt.windows.WPrinterJob;
import javax.swing.*;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Udpchatre implements Runnable{
DatagramSocket socket=null;
private int port;
private String fromName;
public Udpchatre(int port, String fromName) {
this.port = port;
this.fromName = fromName;
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
byte[] bytes = new byte[1024];//准备管道接收数据
// 把管道的数据打包
DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length);
//接受包
socket.receive(packet);
//断开连接
byte[] data=packet.getData();
String s = new String(data,0, data.length);
System.out.println(fromName+":"+s);
if (s.trim().equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭资源
socket.close();
}
}
(3)学生端
package chat;
public class TestStudent {
public static void main(String[] args) {
new Thread(new Udpchatse(2222,"localhost",9999)).start();
new Thread(new Udpchatre(3333,"老师")).start();
}
}
(4)教师端
package chat;
public class TestTeacher {
public static void main(String[] args) {
new Thread(new Udpchatse(4444,"localhost",3333)).start();
new Thread(new Udpchatre(9999,"学生")).start();
}
}