TCP传输
TCP分客户端和服务端,客户端对应的对象是Socket,服务端对应的对象是ServerSocket
客户端在Socket对象建立时就可以去连接指定主机,因为TCP是面向连接的,所以在建立Socket服务时就要有服务端存在并连接成功,形成通路后在该通道进行数据传输。
步骤:
客户端:
1.创建Socket服务并指定要连接的主机和端口。
2.获取Socket流中的输出流(输入流)。
3.通过输出流将数据发送到服务端(或通过输入流读取服务端发送过来的数据)。
4.关闭客户端。
服务端:
1.建立服务端的Socket服务,通过new ServerSocket()并监听一个端口。
2.获取连接过来的客户端对象。通过ServerSocket对象的accept方法,该方法是阻塞式方法。
3.客户端如果发送过来数据,那么服务端要使用对应的客户端对象并获取到该客户端对象的读取流来读取发过来的数据并打印在控制台。
4.关闭服务端。(可选操作)
示例:
publicclass TCPClient {
publicstaticvoid main(String[] args) throws Exception{
//1.创建客户端的Socket服务,指定目的主机和端口。
Socket s = new Socket("127.0.0.1",10003);//如果创建成功,
//就会产生Socket流,形成客户端与服务端的通路,在通路中进行数据来往
//2.为了发送数据应该获取Socket流中的输出流
OutputStream out = s.getOutputStream();
out.write("TCP Client".getBytes());
s.close();
}
}
publicclass TCPServer {
publicstaticvoid main(String[] args) throws Exception{
//建立服务端Socket服务并监听一个端口
ServerSocket ss = new ServerSocket(10003);
//通过accept方法获取连接过来的客户端对象
Socket s = ss.accept();//阻塞式方法
//获取客户端发送过来的数据,使用客户端对象的读取流来读取数据
InputStream in = s.getInputStream();
byte[] buf = newbyte[1024];
intlen = in.read(buf);
System.out.println(new String(buf,0,len));
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip);
s.close();//服务端要关对方,但是服务端自身不一定要关闭
}
}
TCP客户端与服务端的互访。
需求:客户端给服务端发送数据,服务端收到后给客户端反馈信息。
客户端:
1.建立Socket服务,指定要连接的主机和端口。
2.获取Socket流中的输出流,将数据写入到流中,通过网络发送给服务端。
3.获取Socket流中的输入流,将服务端反馈的数据获取并打印。
4.关闭客户端资源。
publicclass TCPClient2 {
publicstaticvoid main(String[] args) throwsException {
Socket s = new Socket("127.0.0.1",10004);
OutputStream out = s.getOutputStream();
out.write("服务端你好!".getBytes());
InputStream in = s.getInputStream();
byte[] buf = newbyte[1024];
intlen = in.read(buf);//读取Socket流阻塞式方法
System.out.println(new String(buf,0,len));
s.close();
}
}
publicclass TCPServer2 {
publicstaticvoid main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(10004);
Socket s = ss.accept();
InputStream in = s.getInputStream();
byte[] buf = newbyte[1024];
intlen = in.read(buf);
System.out.println(new String(buf,0,len));
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip);
OutputStream out = s.getOutputStream();
out.write("收到".getBytes());
s.close();
}
}
需求:建立一个文本转换服务器
客户端给服务端发送文本,服务端会将文本转成大写再返回给客户端,而且客户端可以不断地进行文本转换,当客户端输入over时转换结束。
分析:
客户端:
源:键盘输入
目的:网络设备,网络输出流,操作的是文本数据可以选择字符流。
步骤:
1.建立服务
2.获取键盘录入
3.将数据发送给服务端
4.获取服务端返回的大写数据
5.结束,关资源
publicclass TransClient {
publicstaticvoid main(String[] args) throwsException {
Socket s = new Socket("127.0.0.1",10005);
BufferedReader bufr = new BufferedReader(
new InputStreamReader(System.in));
BufferedWriter bufOut = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
//定义一个Socket读取流,读取服务器返回的大写信息
BufferedReader bufin = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
bufOut.write(line);
bufOut.flush();
String str = bufin.readLine();
System.out.println("Server"+str);
}
bufr.close();
s.close();
}
}
服务端:
源:Socket读取流
目的:Socket输出流
该例子中应该注意的问题:
客户端和服务端都在等待,这是因为客户端和服务端都有阻塞式方法,这些方法没有读到标记,那么就一直在等,而导致两端都在等。
publicclass TransServer {
publicstaticvoid main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10005);
Socket s = ss.accept();
BufferedReader bufr = new BufferedReader(
new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
String line = null;
while((line=bufr.readLine())!=null){
out.println(line.toUpperCase());
}
s.close();
}
}
TCP复制文件
publicclass TextClient {
publicstaticvoid main(String[] args) throws Exception{
Socket s = new Socket("127.0.0.1",10006);
BufferedReader bufr = new BufferedReader(
new FileReader("IPDemo.java"));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
String line = null;
while((line=bufr.readLine())!=null){
out.println(line);
}
s.shutdownOutput();//关闭客户端输出流,相当于给流中加入结束标记-1
BufferedReader bufin = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String str = bufin.readLine();
System.out.println(str);
bufr.close();
s.close();
}
}
publicclass ServerClient {
publicstaticvoid main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(10006);
Socket s = ss.accept();
BufferedReader bufr = new BufferedReader(
new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(new FileWriter("server.txt"),true);
String line = null;
while((line=bufr.readLine())!=null){
out.println(line);
}
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
pw.println("上传成功!");
out.close();
s.close();
}
}
TCP服务端多线程技术上传图片
publicclass UploadPicClient {
publicstaticvoid main(String[] args) throws Exception{
//1.创建客户端Socket
Socket s = new Socket("127.0.0.1",10006);
//2.读取客户端要上传的文件
FileInputStream fis = new FileInputStream("E:\\1.jpg");
//3.获取Socket输出流,将读到的图片数据发送到服务端
OutputStream out = s.getOutputStream();
byte[] buf = newbyte[1024];
int len = 0;
while((len=fis.read(buf))!=-1){
out.write(buf,0,len);
}
//告诉服务端,该客户端数据发送完毕,让服务端停止读取
s.shutdownOutput();
//读取服务端发回的内容
InputStream in = s.getInputStream();
byte[] buf1 = newbyte[1024];
intlenin = in.read(buf1);
String text = new String(buf1,0,lenin);
System.out.println(text);
fis.close();
s.close();
}
}
public class UploadTask implements Runnable{
private Socket s;
UploadTask(Socket s){
this.s = s;
}
@Override
public void run() {
try {
int count = 0;
InputStream in = s.getInputStream();
String ip = s.getInetAddress().getHostAddress();
File dir = new File("E:\\pic");
if(!dir.exists()){
dir.mkdirs();
}
File file = new File(dir,ip+".jpg");;
while(file.exists()){
file = new File(dir,ip+"("+(++count)+").jpg");
}
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while((len=in.read(buf))!=-1){
fos.write(buf,0,len);
}
OutputStream out = s.getOutputStream();
out.write("上传成功!".getBytes());
fos.close();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class UploadPicServer {
public static void main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(10007);
while(true){
Socket s = ss.accept();
new Thread(new UploadTask(s)).start();
}
}
}
URL和URI的区别:
类URL代表一个统一资源定位符,它是指向互联网资源的指针。例如:http://192.168.1.100:8080/myweb/1.html
类URI代表同意资源标识符
每个URL都是URI,但不一定每个URI都是URL,因为URI还包括一些子类,即统一资源名称(URN)。URN命名资源,但不指定如何定位资源。
String str_url = " http://192.168.1.100:8080/myweb/1.html?name=lisi
";
URL url = new URL(str_url);
url.getProtocol();//获取协议
url.getHost();//获取主机
url.getFile();//文件
url.getQuery();//获取参数信息
url.getPort();//端口
url.getPath();//路径
url.openStream();//打开此URL的连接并返回一个用于从该连接读入的InputStream
URLConnection conn = url.openConnection();//获取URL对象的URL连接器对象,将连接封装成了对象。
URLConnection就是java内置的可以解析具体协议的对象,
String value = conn.getHeaderFile("content-Type");//获取http协议的头信息中的文件类型
conn.getInputStream();
TCP分客户端和服务端,客户端对应的对象是Socket,服务端对应的对象是ServerSocket
客户端在Socket对象建立时就可以去连接指定主机,因为TCP是面向连接的,所以在建立Socket服务时就要有服务端存在并连接成功,形成通路后在该通道进行数据传输。
步骤:
客户端:
1.创建Socket服务并指定要连接的主机和端口。
2.获取Socket流中的输出流(输入流)。
3.通过输出流将数据发送到服务端(或通过输入流读取服务端发送过来的数据)。
4.关闭客户端。
服务端:
1.建立服务端的Socket服务,通过new ServerSocket()并监听一个端口。
2.获取连接过来的客户端对象。通过ServerSocket对象的accept方法,该方法是阻塞式方法。
3.客户端如果发送过来数据,那么服务端要使用对应的客户端对象并获取到该客户端对象的读取流来读取发过来的数据并打印在控制台。
4.关闭服务端。(可选操作)
示例:
publicclass TCPClient {
publicstaticvoid main(String[] args) throws Exception{
//1.创建客户端的Socket服务,指定目的主机和端口。
Socket s = new Socket("127.0.0.1",10003);//如果创建成功,
//就会产生Socket流,形成客户端与服务端的通路,在通路中进行数据来往
//2.为了发送数据应该获取Socket流中的输出流
OutputStream out = s.getOutputStream();
out.write("TCP Client".getBytes());
s.close();
}
}
publicclass TCPServer {
publicstaticvoid main(String[] args) throws Exception{
//建立服务端Socket服务并监听一个端口
ServerSocket ss = new ServerSocket(10003);
//通过accept方法获取连接过来的客户端对象
Socket s = ss.accept();//阻塞式方法
//获取客户端发送过来的数据,使用客户端对象的读取流来读取数据
InputStream in = s.getInputStream();
byte[] buf = newbyte[1024];
intlen = in.read(buf);
System.out.println(new String(buf,0,len));
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip);
s.close();//服务端要关对方,但是服务端自身不一定要关闭
}
}
TCP客户端与服务端的互访。
需求:客户端给服务端发送数据,服务端收到后给客户端反馈信息。
客户端:
1.建立Socket服务,指定要连接的主机和端口。
2.获取Socket流中的输出流,将数据写入到流中,通过网络发送给服务端。
3.获取Socket流中的输入流,将服务端反馈的数据获取并打印。
4.关闭客户端资源。
publicclass TCPClient2 {
publicstaticvoid main(String[] args) throwsException {
Socket s = new Socket("127.0.0.1",10004);
OutputStream out = s.getOutputStream();
out.write("服务端你好!".getBytes());
InputStream in = s.getInputStream();
byte[] buf = newbyte[1024];
intlen = in.read(buf);//读取Socket流阻塞式方法
System.out.println(new String(buf,0,len));
s.close();
}
}
publicclass TCPServer2 {
publicstaticvoid main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(10004);
Socket s = ss.accept();
InputStream in = s.getInputStream();
byte[] buf = newbyte[1024];
intlen = in.read(buf);
System.out.println(new String(buf,0,len));
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip);
OutputStream out = s.getOutputStream();
out.write("收到".getBytes());
s.close();
}
}
需求:建立一个文本转换服务器
客户端给服务端发送文本,服务端会将文本转成大写再返回给客户端,而且客户端可以不断地进行文本转换,当客户端输入over时转换结束。
分析:
客户端:
源:键盘输入
目的:网络设备,网络输出流,操作的是文本数据可以选择字符流。
步骤:
1.建立服务
2.获取键盘录入
3.将数据发送给服务端
4.获取服务端返回的大写数据
5.结束,关资源
publicclass TransClient {
publicstaticvoid main(String[] args) throwsException {
Socket s = new Socket("127.0.0.1",10005);
BufferedReader bufr = new BufferedReader(
new InputStreamReader(System.in));
BufferedWriter bufOut = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
//定义一个Socket读取流,读取服务器返回的大写信息
BufferedReader bufin = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
bufOut.write(line);
bufOut.flush();
String str = bufin.readLine();
System.out.println("Server"+str);
}
bufr.close();
s.close();
}
}
服务端:
源:Socket读取流
目的:Socket输出流
该例子中应该注意的问题:
客户端和服务端都在等待,这是因为客户端和服务端都有阻塞式方法,这些方法没有读到标记,那么就一直在等,而导致两端都在等。
publicclass TransServer {
publicstaticvoid main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10005);
Socket s = ss.accept();
BufferedReader bufr = new BufferedReader(
new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
String line = null;
while((line=bufr.readLine())!=null){
out.println(line.toUpperCase());
}
s.close();
}
}
TCP复制文件
publicclass TextClient {
publicstaticvoid main(String[] args) throws Exception{
Socket s = new Socket("127.0.0.1",10006);
BufferedReader bufr = new BufferedReader(
new FileReader("IPDemo.java"));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
String line = null;
while((line=bufr.readLine())!=null){
out.println(line);
}
s.shutdownOutput();//关闭客户端输出流,相当于给流中加入结束标记-1
BufferedReader bufin = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String str = bufin.readLine();
System.out.println(str);
bufr.close();
s.close();
}
}
publicclass ServerClient {
publicstaticvoid main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(10006);
Socket s = ss.accept();
BufferedReader bufr = new BufferedReader(
new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(new FileWriter("server.txt"),true);
String line = null;
while((line=bufr.readLine())!=null){
out.println(line);
}
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
pw.println("上传成功!");
out.close();
s.close();
}
}
TCP服务端多线程技术上传图片
publicclass UploadPicClient {
publicstaticvoid main(String[] args) throws Exception{
//1.创建客户端Socket
Socket s = new Socket("127.0.0.1",10006);
//2.读取客户端要上传的文件
FileInputStream fis = new FileInputStream("E:\\1.jpg");
//3.获取Socket输出流,将读到的图片数据发送到服务端
OutputStream out = s.getOutputStream();
byte[] buf = newbyte[1024];
int len = 0;
while((len=fis.read(buf))!=-1){
out.write(buf,0,len);
}
//告诉服务端,该客户端数据发送完毕,让服务端停止读取
s.shutdownOutput();
//读取服务端发回的内容
InputStream in = s.getInputStream();
byte[] buf1 = newbyte[1024];
intlenin = in.read(buf1);
String text = new String(buf1,0,lenin);
System.out.println(text);
fis.close();
s.close();
}
}
public class UploadTask implements Runnable{
private Socket s;
UploadTask(Socket s){
this.s = s;
}
@Override
public void run() {
try {
int count = 0;
InputStream in = s.getInputStream();
String ip = s.getInetAddress().getHostAddress();
File dir = new File("E:\\pic");
if(!dir.exists()){
dir.mkdirs();
}
File file = new File(dir,ip+".jpg");;
while(file.exists()){
file = new File(dir,ip+"("+(++count)+").jpg");
}
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while((len=in.read(buf))!=-1){
fos.write(buf,0,len);
}
OutputStream out = s.getOutputStream();
out.write("上传成功!".getBytes());
fos.close();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class UploadPicServer {
public static void main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(10007);
while(true){
Socket s = ss.accept();
new Thread(new UploadTask(s)).start();
}
}
}
URL和URI的区别:
类URL代表一个统一资源定位符,它是指向互联网资源的指针。例如:http://192.168.1.100:8080/myweb/1.html
类URI代表同意资源标识符
每个URL都是URI,但不一定每个URI都是URL,因为URI还包括一些子类,即统一资源名称(URN)。URN命名资源,但不指定如何定位资源。
String str_url = " http://192.168.1.100:8080/myweb/1.html?name=lisi
";
URL url = new URL(str_url);
url.getProtocol();//获取协议
url.getHost();//获取主机
url.getFile();//文件
url.getQuery();//获取参数信息
url.getPort();//端口
url.getPath();//路径
url.openStream();//打开此URL的连接并返回一个用于从该连接读入的InputStream
URLConnection conn = url.openConnection();//获取URL对象的URL连接器对象,将连接封装成了对象。
URLConnection就是java内置的可以解析具体协议的对象,
String value = conn.getHeaderFile("content-Type");//获取http协议的头信息中的文件类型
conn.getInputStream();