TCP模型下基础的Client-Server发送消息与接收消息
Sever:
package Net;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务器端的socket对象
ServerSocket ss=new ServerSocket(1998);
//侦听客户端的连接
Socket s=ss.accept();
//获取输入流,读数据
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys,0,len);
System.out.println(data);
s.close();
ss.close();
}
}
Client:
package Net;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端Socket对象
Socket s=new Socket(InetAddress.getByName("LAPTOP-ATCGV4AQ"),1998);
//获取输出流,写数据
OutputStream os=s.getOutputStream();
os.write(" hello,tcp,我来辣".getBytes());
s.close();
}
}
执行结果:
TCP模型下Client-Server同时发送消息与接收消息
Client:
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端Socket对象
Socket s=new Socket(InetAddress.getByName("LAPTOP-ATCGV4AQ"),1998);
//获取输出流,写数据
OutputStream os=s.getOutputStream();
os.write("hello,tcp,我来辣".getBytes());
InputStream is=s.getInputStream();
byte[] bys=new byte[1024];
int len=is.read(bys);
String data=new String(bys,0,len);
System.out.println("客户端接收到:"+data);
s.close();
}
}
Server:
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务器端的socket对象
ServerSocket ss=new ServerSocket(1998);
//侦听客户端的连接
Socket s=ss.accept();
//获取输入流,读数据
InputStream is=s.getInputStream();
byte[] bys=new byte[1024];
int len =is.read(bys);
String data=new String(bys,0,len);
System.out.println(data);
OutputStream os=s.getOutputStream();
os.write("客户端接收到数据了".getBytes());
s.close();
ss.close();
}
}
执行结果:
TCP模型下Client-Server使用字符流发送消息与接收消息并且只有当Client发送886时结束通信
Client:
package Net.TCP.Client01Demo;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
public class Client {
public static void main(String[] args) throws IOException {
Socket s = new Socket(InetAddress.getByName("LAPTOP-ATCGV4AQ"), 1998);
//数据来自于键盘录入,直到输入的数据是886为止
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//封装字节流输出
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//s.getOutputStream()字节流,new OutputStreamWriter转换为字符流,new BufferedWriter为了与上面的BufferedReader对应而采用
BufferedReader brReceive = new BufferedReader(new InputStreamReader(s.getInputStream()));//获取收到的回复信息
String Line;
while ((Line = br.readLine()) != null) {
if ("886".equals(Line)) {
System.out.println("886,结束通信");
break;
} else {
//获取输出流对象,但是此方法为字节流方法,我们采取自己封装字节流的方式传输
//OutputStream os = s.getOutputStream();
//os.write(Line.getBytes());
//字符流输出数据给server端
bw.write(Line);
bw.newLine();
bw.flush();
}
System.out.println("收到Server回复 : "+brReceive.readLine());
}
br.close();
bw.close();
brReceive.close();
s.close();
}
}
Server:
package Net.TCP.Client01Demo;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(1998);
Socket s = ss.accept();
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String Line;
while ((Line=br.readLine())!=null){
System.out.println("本地接受到数据"+Line);
//回复收到
bw.write("服务器已收到数据"+Line);
bw.newLine();
bw.flush();
if ("886".equals(br)){
break;
}
}
bw.close();
br.close();
s.close();
ss.close();
}
}
Client:
public class Client {
public static void main(String[] args) throws IOException {
Socket s=new Socket(InetAddress.getByName("LAPTOP-ATCGV4AQ"), 1998);
BufferedReader br=new BufferedReader(new FileReader("ieda_test\\src\\IO\\fos.txt"));
//BufferedReader br2=new BufferedReader(new InputStreamReader(new FileInputStream("ieda_test\\src\\IO\\fos.txt")));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//s.getOutputStream()字节流,new OutputStreamWriter转换为字符流,new BufferedWriter为了与上面的BufferedReader对应而采用
BufferedReader brReceive = new BufferedReader(new InputStreamReader(s.getInputStream()));//获取收到的回复信息
String Line;
while ((Line = br.readLine()) != null) {
//获取输出流对象,但是此方法为字节流方法,我们采取自己封装字节流的方式传输
//OutputStream os = s.getOutputStream();
//os.write(Line.getBytes());
//字符流输出数据给server端
bw.write(Line);
bw.newLine();
bw.flush();
// System.out.println("收到Server回复 : "+brReceive.readLine());
//brReceive.readLine()会导致一直等到服务器端的回复数据才会停止,所以这个地方容易死等
}
//自定义结束标记
// bw.write("886");
// bw.newLine();
// bw.flush();
s.shutdownOutput();//这个shutdown的含义就是通过s向server端口发送终止信号,表明已经传输完成了
br.close();
bw.close();
brReceive.close();
s.close();
}
}
这个shutdown的含义就是通过s向server端口发送终止信号,表明已经传输完成了 这样sever端就可以停止接受client端的消息而不会进入无限等待中。
Server:
package Net.TCP.Client02Demo;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(1998);
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//把接收到的数据复制到另外一个本地文件中
BufferedWriter bwLocal = new BufferedWriter(new FileWriter("ieda_test\\src\\Net\\TCP\\Client02Demo\\Local.txt"));
String Line;
while ((Line = br.readLine()) != null) {
//复制到本地
bwLocal.write(Line);
bwLocal.newLine();
bwLocal.flush();
System.out.println("本地接受到数据" + Line);
}
//回复收到
bw.write("服务器已收到数据" + Line);
bw.newLine();
bw.flush();
bw.close();
br.close();
s.close();
ss.close();
bwLocal.close();
}
}
执行结果:
文件上传成功!
需要注意的是:在Client中brReceive.readLine()会导致一直等到服务器端的回复数据才会停止,所以这个地方容易死等。
Client:
public class Client {
public static void main(String[] args) throws IOException {
Socket s=new Socket(InetAddress.getByName("LAPTOP-ATCGV4AQ"), 1998);
BufferedReader br=new BufferedReader(new FileReader("ieda_test\\src\\IO\\fos.txt"));
//BufferedReader br2=new BufferedReader(new InputStreamReader(new FileInputStream("ieda_test\\src\\IO\\fos.txt")));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//s.getOutputStream()字节流,new OutputStreamWriter转换为字符流,new BufferedWriter为了与上面的BufferedReader对应而采用
BufferedReader brReceive = new BufferedReader(new InputStreamReader(s.getInputStream()));//获取收到的回复信息
String Line;
while ((Line = br.readLine()) != null) {
//字符流输出数据给server端
bw.write(Line);
bw.newLine();
bw.flush();
}
s.shutdownOutput();
System.out.println("收到Server回复 : "+brReceive.readLine());
br.close();
bw.close();
brReceive.close();
s.close();
}
}
Server:
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(1998);
//为每个客户端Client开启一个线程
while (true){
Socket s=ss.accept();
new Thread(new ServerThread(s)).start();
}
}
}
ServerThread:
public class ServerThread implements Runnable {
public Socket s;
public ServerThread(Socket s) {
this.s=s;
}
@Override
public void run() {
//接收数据写到文件中
try {
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
//解决名称冲突问题
int count = 0;
File file =new File("ieda_test\\src\\Net\\TCP\\Client03Demo\\Copy["+count+"].txt");
while (file.exists()){
count++;
file =new File("ieda_test\\src\\Net\\TCP\\Client03Demo\\Copy["+count+"].txt");
}
BufferedWriter bw=new BufferedWriter(new FileWriter(file));
String line;
while ((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
//给client反馈收到
BufferedWriter bwServer=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bwServer.write("文件上传成功");
bwServer.newLine();
bwServer.flush();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
执行结果:
文件上传成功!