----------------------- android培训、java培训、java学习型技术博客、期待与您交流! ----------------------
4. TCP网络编程
面向连接,客户端和服务端
连接效率低
安全可靠协议
适合大数据传输
客户端需要与服务端建立连接,才可以通信
一旦连接建立好了,靠的是IO流进行通信
TCP中的IO流对象,是不可以创建的
流对象是通过Socket服务获取出来的
一但连接成功,在连接的通路,IO流已经建立好了
|-- Socket客户端Socket服务,java.net.Socket
|-- 构造
|-- getInputStream()获取字节输入流,读取服务端发回的数据
|-- getOutputStream()获取字节输出流,向服务器发送数据
|-- shutdownOutput()向服务器写一个结束标记
|-- ServerSocket 服务器的Socket服务,java.net.ServerSocket
|-- 构造
|-- getInputStream()获取字节输入流,读取客户端发送的数据
|-- getOutputStream()获取字节输出流,向客户端发送数据
|-- accept() 获取客户端的连接对象
练习:tcp传输数据
/*
演示tcp传输。 tcp分客户端和服务端。 Socket。 ServerSocket
客户端,
通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。
因为tcp是面向连接的。所以在建立socket服务时,
就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。
需求:给服务端发送给一个文本数据。
步骤:
1. 建立Socket服务
Socket(String host, int port)
2. 获取字节输出流
通过Socket对象获取 getOutputStream()
3. 写数据
4. 关闭资源
*/
import java.io.*;
import java.net.*;
class TcpClient {
public static void main(String[] args)throws Exception{
//创建客户端的socket服务。指定目的主机和端口
Socket s = newSocket("192.168.1.254",10003);
//向服务端发送数据, 字节输出流
//为了发送数据,应该获取socket流中的输出流。
OutputStream out =s.getOutputStream();
out.write("TCP收到了吗".getBytes()); //不能写字符串 转成字节数据
/* 客户端和服务端的互访------获取服务端发来的数据,获取字节输入流
InputStream in = s.getInputStream();
byte[] buf = new byte[10];
int len = 0 ;
len = in.read(buf);
System.out.println(new String(buf,0,len));
*/
s.close();
}
}
/*
需求:定义端点接收数据并打印在控制台上。
服务端:
1,建立服务端的socket服务。ServerSocket(); 并监听一个端口。
2,使用accept获得客户端连接对象
通过ServerSokcet的 accept方法。没有连接就会等,所以这个方法阻塞式的。
3,客户端如果发过来数据,那么服务端要使用对应的客户端连接对象,并获取字节输入流,读取客户端的数据,打印在控制台。
4,关闭服务端。(可选)
*/
class TcpServer {
public static void main(String[] args)throws Exception {
//建立服务端socket服务。并监听一个端口。
ServerSocket ss = new ServerSocket(10003);
//通过accept方法获取连接过来的客户端对象。
while(true)
{
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(newString(buf,0,len));
/* 客户端和服务端的互访------服务端发送消息给客户端,获取字节输出流
OutputStream out = s.getOutputStream();
out.write("OK收到了".getBytes());
*/
s.close();//关闭客户端.
}
//ss.close();
}
}
TCP 案例:通过键盘录入数据,发到服务器,服务器转大写,发回
/*
TCP转成大写客户端
实现步骤:
1. 获取键盘输入
2. 建立Socket对象
3. 读取一行,向服务端发送一行
4. 获取服务端发回的大写数据
*/
import java.net.*;
import java.io.*;
class TCPToUpperCaseClient {
public static void main(String[] args) throws Exception{
//1.定义读取键盘数据的流对象。
BufferedReader bfr = new
BufferedReader(new InputStreamReader(System.in));
//2.建立Socket服务 ,客户端
Socket s = new Socket("127.0.0.1",10000);
//3.获取字节输出流,向服务端写数据
//OutputStream out = s.getOutputStream();
//读取一行,向服务端发送一行 打印流,数据目的,字符,字节
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);//使用打印流自动刷新
//4 定义一个socket读取流,读取服务端返回的大写信息。获取大写数据,字节输入流
BufferedReader bfrIn = new
BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line = bfr.readLine())!=null){
if("886".equals(line))
break;
pw.println(line);
String upperCase = bfrIn.readLine();
System.out.println(upperCase);
}
//关闭资源的时候,关闭自己创建的流对象
bfr.close();
s.close();
}
}
/*
TCP转成大写服务端
实现步骤:
1. 建立Socket服务
2. 获取客户端连接对象
3. 读取一行,转成大写,发回客户端
*/
import java.net.*;
import java.io.*;
class TCPToUpperCaseServer{
public static void main(String[] args) throws Exception{
//建立服务端的Socket服务 ServerSocket
ServerSocket ss = new ServerSocket(10000);
while(true){
Socket s = ss.accept();//获取客户端连接对象
//获取字节输入流,读取客户端数据,Socket对象获取
BufferedReader bfrIn =
new BufferedReader(new InputStreamReader(s.getInputStream()));
//读取一行,转成大写,发回客户端,打印流
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
String line = null;
while((line = bfrIn.readLine())!=null){
pw.println(line.toUpperCase());
}
}
}
}
TCP 案例:
客户端上传图片给服务端进行保存,一个服务端通过可以允许
多个客户端一起上传,多线程
/*
TCP客户端上传图片
*/
import java.net.*;
import java.io.*;
import java.util.*;
class TCPUploadClient{
public static void main(String[] args){
Socket s = null;
FileInputStream fis = null;
try{
s = new Socket("127.0.0.1",10000); //建立Socket
fis = new FileInputStream("c:\\a.jpg"); //字节流读取文件
OutputStream out = s.getOutputStream();//获取字节输出流,Socket对象
int len = 0 ;
byte[] buf = new byte[1024];
while((len = fis.read(buf))!=-1){
out.write(buf,0,len);
}
s.shutdownOutput() ; //结束标记
//发送完毕的时候,获取服务端发回的上传成功字样
BufferedReader bfr = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = bfr.readLine();
System.out.println(line);
}
catch (Exception e){
System.out.println(e);
}
finally{
try
{
if(fis!=null)
fis.close();
}
catch (Exception e)
{
System.out.println(e);
}
try
{
if(s!=null)
s.close();
}
catch (Exception e)
{
System.out.println(e);
}
}
}
/*
* 服务器端,实现多线程程序,同时为多个客户端服务
*/
class Upload implements Runnable{
private Socket s ;
Upload(Socket s){this.s = s;}
public void run(){
FileOutputStream fos = null;
//客户端的连接已经有le
try{
File file = new File("d:\\upload");
if(!file.exists())
file.mkdirs();
String filename = "itcast"+new Random().nextInt(10000)+System.currentTimeMillis()+".jpg";
//获取字节输入流
InputStream in = s.getInputStream();
//字节输出流,负责向本地硬盘写文件
fos = new FileOutputStream(file+File.separator+filename);
byte[] buf = new byte[1024];
int length = 0 ;
while((length = in.read(buf))!=-1){
fos.write(buf, 0, length);
}
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip);
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
pw.println("上传成功");
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(fos!=null)
fos.close();
}catch(IOException e){}
try{
if(s!=null)
s.close();
}catch(Exception e){}
}
}
}
public class TCPServerUploadThread {
public static void main(String[] args)throws Exception {
ServerSocket ss = new ServerSocket(10000);
while(true){
Socket s = ss.accept();
new Thread(new Upload(s)).start();
}
}
}
----------------------- android培训、java培训、java学习型技术博客、期待与您交流! ----------------------