TCP通信程序
TCP通信原理
TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,从而在通信的两端形成网络虚拟链路,一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信
Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生O流来进行网络通信
TCP发送数据的步骤
- 创建客户端的socket对象(Socket)
Socket(String host,int port) - 获取输出流,写数据
OutputStream getOutputStream() - 释放资源
void close()
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端的Socket
//Socket s=new Socket(InetAddress.getByName("127.0.0.1"),10000);
Socket s=new Socket("127.0.0.1",10000);
//获取输出流写数据
OutputStream os=s.getOutputStream();
os.write("Hello TCP!".getBytes());
s.close();
}
}
TCP接收数据的步骤
- 创建服务器端的socket对象(ServerSocket)
ServerSocket(int port) - 监听客户端连接,返回一个对应的Socket对象
Socket accept() - 获取输入流,读数据,并把数据显示在控制台
InputStream getInputStream() - 释放资源
void close()
public class ServerDemo {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(10000);
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();
}
}
TCP通讯程序练习
练习1
- 客户端:发送数据,接收服务器反馈
- 服务器:接收数据,给出反馈
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端的Socket
//Socket s=new Socket(InetAddress.getByName("127.0.0.1"),10000);
Socket s=new Socket("127.0.0.1",10000);
//获取输出流写数据
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();
}
}
public class ServerDemo {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(10000);
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());
ss.close();
}
}
练习2
- 数据来源于键盘录入,直到886结束
- 接收数据在控制台输出
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端的Socket
//Socket s=new Socket(InetAddress.getByName("127.0.0.1"),10000);
Socket s=new Socket("127.0.0.1",10000);
//数据来自键盘录入
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//封装输出流对象,用字符流传输
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while((line=br.readLine())!=null){
if("886".equals(line))
break;
bw.write(line);
bw.newLine();
bw.flush();
// OutputStream os=s.getOutputStream();
// os.write(line.getBytes());
}
s.close();
}
}
public class ServerDemo {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(10000);
Socket s=ss.accept();
InputStream is=s.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
String line;
while((line=br.readLine())!=null){
System.out.println("服务器:"+line);
}
ss.close();
}
}
练习3
服务器将接收到的文本写入文件
public class ServerDemo {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(10010);
Socket s=ss.accept();
InputStream is=s.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
BufferedWriter bw=new BufferedWriter(new FileWriter("s.txt"));
String line;
while((line=br.readLine())!=null){
bw.write("服务器:"+line);
bw.newLine();
bw.flush();
}
bw.close();
ss.close();
}
}
练习4
- 客户端的输入来自文本文件
- 服务器端写入文本文件
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端的Socket
//Socket s=new Socket(InetAddress.getByName("127.0.0.1"),10000);
Socket s=new Socket("127.0.0.1",10010);
//数据来自文本
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("c.txt")));
//封装输出流对象,用字符流传输
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while((line=br.readLine())!=null){
if("886".equals(line))
break;
bw.write(line);
bw.newLine();
bw.flush();
}
br.close();
s.close();
}
}
练习5
- 客户端:数据来自于文本文件,接收服务器反馈
- 服务器:接收到的数据写入文本文件,给出反馈
public class ServerDemo {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(10010);
Socket s=ss.accept();
InputStream is=s.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
BufferedWriter bw=new BufferedWriter(new FileWriter("s.txt"));
String line;
while((line=br.readLine())!=null){
// if("886".equals(line)){
// break;
// }
bw.write("服务器:"+line);
bw.newLine();
bw.flush();
}
//给反馈
BufferedWriter bwServer=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bwServer.write("文件上传成功!");
bwServer.newLine();
bwServer.flush();
bw.close();
ss.close();
}
}
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端的Socket
//Socket s=new Socket(InetAddress.getByName("127.0.0.1"),10000);
Socket s=new Socket("127.0.0.1",10010);
//数据来自文本
BufferedReader br=new BufferedReader(new FileReader("c.txt"));
BufferedReader bbr=new BufferedReader(new InputStreamReader(new FileInputStream("c.txt")));
//封装输出流对象,用字符流传输
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
// //自定义结束标记
// bw.write("886");
// bw.newLine();
// bw.flush();
s.shutdownOutput();
//接受反馈
BufferedReader brClient =new BufferedReader(new InputStreamReader(s.getInputStream()));
String data=brClient.readLine();
System.out.println("服务器反馈:"+data);
br.close();
s.close();
}
}
出现问题:程序一直等待
- 原因:读数据的方法是阻塞式的,
- 解决办法:自定义结束标记;使用shutdownOutput()
练习6
- 客户端:数据来自于文本文件,接收服务器反馈
- 服务器:接收到的数据写入文本文件,给出反馈,代码用线程进行封装,为每一个客户端开启一个线程
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())); BufferedWriter bw=new BufferedWriter(new FileWriter("src/com/itheima07/s.txt")); String line; while ((line= br.readLine())!=null){ bw.write(line); bw.newLine(); bw.flush(); } //给出反馈 BufferedWriter bwServer=new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); bwServer.write("文件上传成功!"); bwServer.newLine(); bwServer.flush(); s.close(); } catch (IOException e) { throw new RuntimeException(e); } } }
public class ServerDemo { public static void main(String[] args) throws IOException { //创建服务器端Socket ServerSocket serverSocket=new ServerSocket(10010); while(true){//监听客户端连接,返回一个Socket对象 Socket s = serverSocket.accept(); //为每个客户端开启一个线程 new Thread(new ServerThread(s)).start(); } } }
public class ClientDemo { public static void main(String[] args) throws IOException { //创建客户端的Socket Socket s=new Socket("127.0.0.1",10010); //数据来自文本 BufferedReader br=new BufferedReader(new FileReader("c.txt")); BufferedReader bbr=new BufferedReader(new InputStreamReader(new FileInputStream("c.txt"))); //封装输出流对象,用字符流传输 BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line; while((line=br.readLine())!=null){ bw.write(line); bw.newLine(); bw.flush(); } s.shutdownOutput(); //接受反馈 BufferedReader brClient =new BufferedReader(new InputStreamReader(s.getInputStream())); String data=brClient.readLine(); System.out.println("服务器反馈:"+data); br.close(); s.close(); } }