(100)TCP:socket、ServerSocket
tcp分为客户端和服务端,客户端对应的对象:Socket;服务端对应 的对象是:ServerSocket
一、需求:给服务端发送一个文本数据,并在服务端打印该数据
客户端
通过查阅socket对象,发现在该对象建立时,就可以去连接指定的主机,因为tcp是面向连接的,所以在建立socket服务时,就要有服务存在,并连接成功,形成通路后,在该通路上进行数据的传输。
import java.io.*;
import java.net.*;
public class client {
public static void main(String[] args)throws Exception {
//创建客户端的socket服务,指定目的主机和端口
Socket s=new Socket("192.168.1.103",10004);
//为了发送数据(写),应该获取socket流中的输出流
OutputStream out=s.getOutputStream();
out.write("hahah".getBytes());
}
}
二、服务端
1,建立服务端的socket服务,ServerSocket(),并且监听一个端口
2,获取连接过来 的客户对象,通过ServerSocket中的accept方法,没连接则会等待,所以这个方法是阻塞式的。
3,客户端如果发送过来数据,那么服务端要使用对应的客户端对象,并根据该对象的读取流来读取发送过来的数据,并且打印在控制台上。
4,关闭服务器(可选)
import java.io.*;
import java.net.*;
public class server {
public static void main(String[] args)throws Exception {
//建立服务端socket服务,并监听一个端口
ServerSocket ss=new ServerSocket(10005);
//通过accept方法获取连接过来的客户端对象
Socket s=ss.accept();
String ip=s.getInetAddress().getHostAddress();
System.out.println(ip+".........connected");
//获取客户端发送过来的数据,通过使用客户端对象的读取流来读取数据
InputStream in=s.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);
System.out.println(new String(buf,0,len));
/*while((len=in.read(buf))!=-1)
{
System.out.println(new String(buf,0,len));
}*/
s.close();
//将客户端关闭的原因是:打印在这里就是服务端给的服务,服务已经结束,为了资源复用
//应在有限的时间内关闭客户端
//在服务端必须将客户端端口关闭,服务端的端口可以不关,流依赖于端口,所以也自动关闭
}
}
二、需求:tcp传输的客户端和服务端的互访即客户端给服务端发送数据,服务端接收后,给可互段反馈信息
客户端
1,建立socket服务,指定要连接的主机和端口
2,获取socket流中的输出流,将数据写入到该流中,通过网络发送给服务端
3,获取socket流中的输入流,将服务端反馈的数据获取到,并打印
4,关闭客户端资源
import java.io.*;
import java.net.*;
public class client1 {
public static void main(String[] args)throws Exception {
//1,建立socket服务,指定要连接主机和端口
Socket s=new Socket("192.168.1.103",10005);
//2,获取socket流中的输出流,将数据写入到该流中
OutputStream out=s.getOutputStream();
out.write("我是客户端,服务端你好".getBytes());
//3,获取socket流中的输入流,将服务端反馈的数据获取,并打印
InputStream in=s.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);
System.out.println(new String(buf,0,len));
//4,关闭资源
s.close();
}
}
Q:先Outputstream,再InputStream,为啥不会在服务端给回应前就程序结束呢?
因为read()方法是阻塞式方法,在此程序中,若服务端没写数据,则客户端读不到数据,一直阻塞在这,直到服务端Outputstream写入数据后,客户端才会从阻塞位置继续往下执行
服务端
public class server1 {
public static void main(String[] args)throws Exception {
//1,建立服务端的socket服务,ServerSocket(),并且监听一个端口
ServerSocket ss=new ServerSocket(10005);
//获取连接过来的客户对象,通过ServerSocket中的accept方法(阻塞式)获取客户端对象
Socket s=ss.accept();
String ip=s.getInetAddress().getHostAddress();
System.out.println(ip+" ........连接上服务器了哈");
//若客户端发送数据,则再服务端用客户端对象读取数据
InputStream in=s.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);
System.out.println(new String(buf,0,len));
Thread.sleep(10000);
//服务端通过客户端对象给客户端发送数据(服务)
OutputStream out=s.getOutputStream();
out.write("我是服务端,客户端你好".getBytes());
s.close();
}
}
三、需求:建立一个文本转换服务器,客户端给服务端发送文本,服务端将文本转成大写再返回给客户端
而且客户端可以不断的进行文本转换,当客户端输入over时,转换结束
分析:客户端
既然是操作设备上的数据,那么就可以要使用io结束,并按照io的操作规律来思考
源:键盘录入
目的:网络设备,网络输出流,操作的是文本数据,可以选择字符流
客户端
import java.net.*;
/*
* 源:键盘录入
* 目的:服务端(向服务器写)
* 目的:读取服务端发来的数据(读)
*/
public class client3 {
public static void main(String[] args)throws Exception {
//创建客户端socket对象,指定目的主机和端口
Socket s=new Socket("192.168.1.103",10006);
//键盘录入
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
//向服务器端写文本数据(因为一行一行的读,所以用修饰),因为要用getOutputStream,所以要字节流转换为字节流
BufferedWriter bufwIn=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//读取服务器端发来的一行数据,因为要用InputStream,还需要将字节流转换为字符流
BufferedReader bufrIn=new BufferedReader(new InputStreamReader(s.getInputStream()));
String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufwIn.write(line);
bufwIn.newLine();//写一行数据,否则服务器无法读取一行数据(关键)
bufwIn.flush();//(关键!!!)
String str=bufrIn.readLine();
System.out.println("server:"+str);
}
bufr.close();
s.close();//In流依赖于s流
}
}
服务器
import java.io.*;
import java.net.*;
public class server3 {
/*
* 源:从客户端读取一行
* 目的:向客户端写入一行
*/
public static void main(String[] args) throws Exception{
ServerSocket ss=new ServerSocket(10006);
//服务功能是否能够完成,首先要判断连接是否连得上
Socket s=ss.accept();
String ip=s.getInetAddress().getHostAddress();
System.out.println(ip+"......connected");
//源
BufferedReader bufr=new BufferedReader(new InputStreamReader(s.getInputStream()));
//目的
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line=null;
while((line=bufr.readLine())!=null)
{
bufw.write(line.toUpperCase());
bufw.newLine();//(关键)
bufw.flush();//(关键)
}
s.close();
}
}
四、将文件上传到