TCP传输:
Socket与ServerSocket
建立客服端与服务端。
建立连接后,通过socket中的IO流进行数据的传输。
关闭Socket。
同样:客服端和服务端也是两个独立的应用程序。
客服端对应的对象是:Socket。服务端对应的对象就是:ServerSocket。
客服端:通过查阅Socket对象,发现在该对象建立时,就可以连接指定的主机。因为tcp是面向连接的,所以在建立scoket服务时,就要有服务端存在。形成通路后,在改通道进行数据的传输。
步骤:
1、创建Socket服务,并指定其连接的端口和ip地址。
2、获取Socket流中的输出流OutputStream,将数据写入流中,通过网络发送给服务端;
3、获取Socket流中的输出流InputStream,获取服务端的反馈信息;
4、关闭资源。
服务端:(阻塞式,等待客服端的连接)
1、建立ServerSocket服务,并监听一个端口
2、通过ServerSocket的accept方法,获取scoket对象。
3、通过Socket对象读取流获取数据
4、通过Socket对象写入流向客服端回馈信息。
5、关闭资源。
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
class TcpClient {
/**
* @param 需求:向服务端发送文本数据
*/
public static void main(String[] args) throws Exception{
//1、创建socket服务。
Socket s=new Socket("192.168.1.12", 10003);
//2、通过Socket获取输出流,向服务端写数据。
OutputStream out=s.getOutputStream();
out.write("你好,我是客服端".getBytes());
s.close();
}
}
class TcpServer {
public static void main(String[] args) throws Exception{
System.out.println("等待客服端连接中........");
ServerSocket ss=new ServerSocket(10003);
Socket s=ss.accept();//获取Socket对象
String ip=s.getInetAddress().getHostAddress();
System.out.println("ip::"+ip+"----connection成功");
InputStream in=s.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);
System.out.println(new String(buf,0,len));
}
}
需求::多客户端上传图片到服务端。利用线程封装服务端执行代码。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 客服端:上传图片
* 思路:
* 1、建立服务,指定连接端口。
* 2、读取本地图片数据
* 3、使用网络流的输出流把图片数据输出
4、传输结束:socket的shutdownOutput()
* 4、接收服务端的反馈信息(通过输入流)
* 5、关闭资源
*
*/
class PicClient2 {
public static void main(String[] args) throws Exception{
Socket s=new Socket("192.168.1.21",10005);
FileInputStream fis=new FileInputStream("f:\\20130221160.jpg");
OutputStream out=s.getOutputStream();
int len=0;
byte[] buf=new byte[1024];
while((len=fis.read(buf))!=-1){
out.write(buf,0,len);
}
s.shutdownOutput();//告诉服务端数据已写完
InputStream in=s.getInputStream();
//接收服务端的返回信息
byte[] bin=new byte[1024];
int lenin=in.read(bin);
System.out.println(new String(bin,0,lenin));
fis.close();
s.close();
}
}
/**
* 服务端:
* 这个服务端有个局限性,当A客户端连接上以后。被服务端获取到以后,就执行具体流程。
* 这是如果B客户端连接,就只有等待。
* 为什么呢?因为服务端还没有处理完A客户端的流程,只有循环执行完过后,才会接收到B客户端对象。
* 所以暂时获取不到B客户端。
* 为了让多个客户端并发同时访问服务端。那么服务端最好把每隔客户端对象封装到单独的线程中去。
* 这样就可以解决多个客户端请求服务端问题。
*
* 如何定义线程??
* 只要明白每个客服端要在服务端执行的代码即可,将该代码封装到run方法中。
*
*
*/
class PicThread implements Runnable{
private Socket s;
public PicThread(Socket s){
this.s=s;
}
@Override
public void run() {
try {
String ip=s.getInetAddress().getHostAddress();
System.out.println(ip+"----connection成功");
//定义图片文件目的
FileOutputStream fos=new FileOutputStream("server3.jpg");
//利用socket读取流,读取客服端的图片数据
InputStream in = s.getInputStream();
byte[] bufIn = new byte[1024];
int lenIn = 0;
while((lenIn=in.read())!=-1)
{
fos.write(bufIn,0,lenIn);
}
OutputStream out=s.getOutputStream();
out.write("图片上传成功".getBytes());
fos.close();
s.close();
} catch (Exception e) {
System.out.println("文件上传失败");
e.printStackTrace();
}
}
}
class PicSever2 {
public static void main(String[] args) throws Exception {
ServerSocket ss=new ServerSocket(10005);
while(true){
Socket s=ss.accept();
new Thread(new PicThread(s)).start();
}
// ss.close();
}
}