java套接字编程集成度很高,容易上手,客户端和服务器互传字符串的代码如下:
server:
package test1;
/*tcp通信服务器端,接收客户端的请求,读取客户端发送的数据,回写数据
*服务器端必须明确:是哪个客户端请求的服务器,所以可以使用accept获取到请求的客户端对象
* 成员方法:accept():
* 返回的是socket
* 服务器的实现步骤:
* 1.创建服务器ServerSocket对象,和系统指定的端口对象
* 2.使用ServerSocket对象中的方法accept获取到请求的客户端对象Socket
* 3.使用网络字节输入流对象读取客户端发送的数据
* 4.获取网络字节输出流getOutputStream,
* 6.使用网络字节输出流中的方法write()给客户端回写数据
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8888);
Socket socket = server.accept();
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024];
int len = is.read(bytes);
System.out.println(new String(bytes,0,len));
OutputStream os = socket.getOutputStream();
os.write("收到谢谢".getBytes());
//处理套接字关闭
socket.close();
//服务器端坚挺socket关闭
server.close();
}
}
client:
package test1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class TcpClient {
public static void main(String[] args) throws IOException {
// 服务器未运行在这个端口上的时候会抛出未连接异常
Socket socket = new Socket("127.0.0.1",8888);
OutputStream os = socket.getOutputStream();
//获取服务器端的数据
os.write("你好服务器".getBytes());
//向服务器端写入数据
InputStream is = socket.getInputStream();
byte[] data = new byte[1024];
int len = is.read(data);
System.out.println(new String(data,0,len));
socket.close();
}
}
通过多线程上传文件的代码如下:
client:
package fileTransfre;
import java.io.*;
import java.net.Socket;
public class TCPClient {
public static void main(String[] args) throws IOException {
//1.创建本地字节输入流绑定数据源
FileInputStream fis = new FileInputStream("C:\\Users\\lenovo\\Desktop\\20190824142136.jpg");
//2.创建客户端Socket对象,构造方法中指定了IP地址和端口号
Socket socket = new Socket("127.0.0.1",8888);
//获取网络字节输出流对象
OutputStream os = socket.getOutputStream();
//使用本地字节输入流read方法读取本地图片,并且通过write方法向服务器传递
int len = 0;
byte[] bytes = new byte[1024];
while((len = fis.read(bytes))!=-1){
os.write(bytes,0,len);
}
// 写入结束标记
socket.shutdownOutput();
// 读取服务器送过来的资源
InputStream is = socket.getInputStream();
while((len = is.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
fis.close();
socket.close();
}
}
server:
package fileTransfre;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;
public class TCPServer {
public static void main(String[] args) throws IOException {
// 1.创建一个服务器端的监听套接字对象,指定响应的端口号
ServerSocket serverSocket = new ServerSocket(8888);
// 2.获取请求的socket对象
// 让服务器一直处于监听状态,即死循环状态(accept是阻塞方法,知道产生连接才开始执行)
while(true){
Socket socket = serverSocket.accept();
// 使用多线程技术对客户端请求进行线程分发,提高服务器的执行效率
// 在子线程中完成文件的上传
// 使用lambda表达式完成Runnable实例的创建
new Thread(() -> {
try{
// 3.获取网络输入字节流
InputStream input = socket.getInputStream();
// 4.创建文件,判断文件夹是否存在,不存在则创建文件夹
File file = new File("C:\\upload");
if(!file.exists()){
file.mkdir();
}
String fileName = UUID.randomUUID().toString().replace("-","")+".jpg";
// 5.文件字节输出流,将文件输出到指定的目录下
FileOutputStream fos = new FileOutputStream(file+"\\"+fileName);
// 6.使用网络字节输入流读取客户端上传的文件
int len = 0;
byte[] bytes = new byte[1024];
// 7.读取到的文件不是空的就将其写入文件中
// 服务器端不会接收到-1,因为客户端不会向服务器传输-1
while((len = input.read(bytes))!=-1){
fos.write(bytes,0,len);
}
// 7.向客户端回传数据
socket.getOutputStream().write("上传成功".getBytes());
System.out.println("服务器端上传成功");
}catch (Exception e) {
e.printStackTrace();
}
}).start();
}
// 8.释放资源
// fos.close();
// serverSocket.close();
// input.close();
}
}