socket通信
socket通讯主要基于两种协议:一种是TCP协议,一种是UDP协议
1.TCP
TCP通信:tcp属于全双工连接,可以保证数据传输的安全性。一般分为服务器端和客户端。使用TCP协议连接所传递的数据不会丢失。通常使用在发短信,文件传输,发邮件等
测试代码:
服务器端:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpFileServer {
public static void main(String[] args) throws Exception {
//创建服务器
ServerSocket serverSocket = new ServerSocket(8888);
//监听服务器
Socket socket = serverSocket.accept();
//创建输入流
InputStream is = socket.getInputStream();
//创建文件输出流
FileOutputStream fos = new FileOutputStream(new File("D:\\LianXi\\Java\\demoLX\\src\\com\\demo1\\receive.png"));
byte[] buffer = new byte[1024];
int len;
while((len=is.read(buffer))!=-1){
fos.write(buffer,0,len);
}
//通知服务器我已经发送完毕
OutputStream outputStream = socket.getOutputStream();
outputStream.write("我已经接收完毕".getBytes());
outputStream.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
客户端:
package com.demo1;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class TcpFile {
public static void main(String[] args) throws Exception {
//创建客户端
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 8888);
//创建输出流
OutputStream os = socket.getOutputStream();
//创建文件输出流
FileInputStream fos = new FileInputStream(new File("D:\\LianXi\\Java\\demoLX\\src\\com\\demo1\\aaa.png"));
int len=0;
byte[] buffer = new byte[1024];
while((len=fos.read(buffer))!=-1){
os.write(buffer,0,len);
}
//本次传输以及完成
socket.shutdownOutput();
//接收
InputStream stream = socket.getInputStream();
//内存转化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len1;
byte[] buffer1 = new byte[1024];
while((len1=stream.read(buffer1))!=-1){
baos.write(buffer1,0,len1);
}
System.out.println(baos.toString());
baos.close();
stream.close();
os.close();
socket.close();
}
}
2.UDP
UDP是基于无连接的协议,不能保证数据的可靠性。
下面是用UDP实现多线程聊天室。
TalkSend
package com.demo2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
public class TalkSend implements Runnable{
DatagramSocket socket=null;
InetAddress localhost=null;
BufferedReader reader=null;
private int fromPost;
private String toIp;
private int toPost;
public TalkSend(int fromPost,String toIp,int toPost) {
this.fromPost=fromPost;
this.toIp=toIp;
this.toPost=toPost;
try {
//建立一个socket连接
socket = new DatagramSocket();
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true){
String str= null;
try {
str = reader.readLine();
//封装成包,参数:数据,数据起始长度,地址,端口号
DatagramPacket datagramPacket = new DatagramPacket(str.getBytes(),0,str.getBytes().length,
new InetSocketAddress(this.toIp,this.toPost));
//发送包
socket.send(datagramPacket);
if (str.equals("by")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
TalkReceive
package com.demo2;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class TalkReceive implements Runnable{
private int port;
private String MessFrom;
DatagramSocket socket=null;
public TalkReceive(int port,String MessFrom) {
this.MessFrom=MessFrom;
this.port=port;
//创建socket对象
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
//监听数据
while(true){
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
//接收数据
socket.receive(packet);
String str=new String(packet.getData()).trim();
System.out.println(MessFrom+":"+str);
if (str.equals("by")){
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
socket.close();
}
}
TalkStudent
package com.demo2;
public class TalkStudent {
public static void main(String[] args) {
new Thread(new TalkSend(7777,"localhost",8888)).start();
new Thread(new TalkReceive(9999,"老师")).start();
}
}
TalkTeacher
package com.demo2;
public class TalkTeacher {
public static void main(String[] args) {
new Thread(new TalkSend(5555,"localhost",9999)).start();
new Thread(new TalkReceive(8888,"学生")).start();
}
}
放在同一目录下运行TalkStudent和TalkTeacher两个文件
运行结果:
3.TCP和UDP的区别:
可靠性 | 连接性 | 传输效率 | 应用场景 | |
---|---|---|---|---|
TCP | 可靠 | 面向连接的 | 传输效率低 | 文件传输,对数据可靠性要求高的传输。 |
UDP | 不可靠 | 无连接的 | 传输效率高 | 视频传输,流媒体。 |
TCP/UDP协议更深层次的理解,三次握手,四次挥手等可以参考这篇文章:TCP/UDP协议
想了解更多的Java知识,可以关注我的微信公众号Java小羽。