java网络编程-----TCP通信

一、Socket的定义

 表示 : 一个Socket就是IP地址和端口号(范围是0~65535)组成,简单理解为ip地址加端口号。

   (1)套接字(Socket)开发网络应用程序被广泛采用,以至于成为事实上的标准。

   (2)  Socket是一个抽象概念,一个应用程序通过一个Socket建立一个远程连接,它的内部通过TCP/IP协议把数据传输到网路。

(3)通信的两端都要有Socket,是两台机器间通信的端点。

  (4)  Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输。

  (5) 一般主动发起通信的应用程序属客户端(一个进程监听),等待通信请求的为服务端(另一个进程)

请添加图片描述

二、TCP通信原理

        TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Scoket对象,从而在通信两端形成网络虚拟链路,一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信。

        Java对基本TCP协议的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生IO流来进行网络通信。

    1. 服务器端

          java标准提升了ServerSocket来实现对指定的IP和指定端口的监听。

    (1) 创建服务器端的Socket对象(ServerScoket)
    ServerSocket(int port);
      (2)  监听客户端连接,返回一个Socket对象
  Socket accept();
    (3)获取输入流,读数据,并把数据显示在控制台
  InputStream getInputStream();
    (4)释放资源
       选中代码块(快捷键:shift+alt+z)

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
    public static void main(String[] args) throws IOException {

        //没有指定ip地址,表示在计算机的所有网络接口上进行监听.
        //创建服务器端的Socket对象
        ServerSocket ss = new ServerSocket(10086);

        //监听客户端连接 并返回Socket对象
        Socket s = ss.accept();

        //获取输入流
       BufferedReader reader=new BufferedReader(                                       
       new  InputStreamReader(s.getInputStream());

        String data  = reader.readLine();

        System.out.println(data);

        //释放资源
        ss.close();

    }
}

    2. 客户端

       (1)创建客户端的Socket对象(Socket)
     Socket(String host,int port);
      ( 2)获取输出流,写数据
     OutputStream getOutputStream();
      ( 3)释放资源
       选中代码块(快捷键:shift+alt+z)

import java.io.OutputStream;
import java.net.Socket;

public class SendDemo {
    public static void main(String[] args) throws Exception {
        //创建客户端的Socket对象
        //Socket(InetAddress address,int port)
        // Socket s = new Socket(InetAddress.getByName("192.168.199.148"),10086);
        Socket s = new Socket("192.168.199.148",10086); //底层会将地址字符串转换InetAddress对象

        //获取输出流
       BufferedWriter writer = new BufferedWriter(new 
                         OutputStreamWriter(client.getOutputStream()));
 
        writer.write("hellojava");

        //释放资源
        s.close();

    }
}

 3.Socket流

      TCP是一种基于流的协议,服务器端和客户端都使用Socket实例进行网络通信,因此,使用InputStream和OutputStream来封装Scket的数据流.

// 用于读取网络数据:
InputStream in = sock.getInputStream();

// 用于写入网络数据:
OutputStream out = sock.getOutputStream();

        写入网络数据,必须调用flush()方法。如果不调用,我们的客户端和服务器端可能会收不到数据,这样做的目的是为了提高传输效率。因为并不是一写入就立刻发送到网络,而是先写入缓冲区,直到缓冲区满了以后,才会一次性发送到网络。

三、 应用案例

例:上传一张照片

 服务器端(需要一个输入缓冲流和一个输出缓冲流)

     输入流:读取来自客户端发送的图片文件流
     输出流:写入本地图片

public class ServerTest {
  public static void main(String[] args) {
	  
	  //服务器端
	try {
	  ServerSocket  server=new ServerSocket(8848);
	  
	  //服务器进入等待状态
	  //如果有客户端连接时,该方法返回此客户端的Socket
	  Socket  client=server.accept();
	  //真正ip地址
	 InetAddress clientNetAddress= client.getInetAddress();
	 
	 System.out.println(clientNetAddress);
	// System.out.println(clientNetAddress.getHostAddress());
	 //字符串地址
	 System.out.println("客户端"+clientNetAddress.getHostAddress()+"开始连接........");
	 
	 //接收来自客户端上传的图片
	 //输入流:读取来自客户端发送的图片文件流
	 //输出流:写入本地图片
	 String imageName=clientNetAddress.getHostAddress().replace("\\.", "-");

	 try (InputStream in = client.getInputStream();
			BufferedInputStream bis = new BufferedInputStream(in);
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\娱乐\\"+imageName+".jpg"))) {
		//每次读取来自客户端的图片文件流
		 //写入本地
		 byte[] buff=new byte[1024];
		 int len=-1;
		 while((len=bis.read(buff))!=-1) {
			 bos.write(buff, 0, len);
		 }
		 
		 System.out.println("图片读取完毕");
		 
		 //输出提示信息=》客户端
		try( BufferedWriter  writer=new BufferedWriter(new OutputStreamWriter(client.getOutputStream()))){
			writer.write("successed!!");
		}
	 }
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}}

 

  

客户端(需要一个输入缓冲流和一个输出缓冲流)

public class Demo {
	public static void main(String[] args) {

		// 192.168.254.149
		// 客户端
		try (Socket s = new Socket("192.168.43.15", 8848);
				OutputStream out = s.getOutputStream();
				BufferedInputStream bis = new BufferedInputStream(
						new FileInputStream("D:\\OneDrive\\图片\\本机照片\\青海.jpg"))) {
			byte[] buffer = new byte[1024];
			int len = -1;
			while ((len = bis.read(buffer)) != -1) {
				out.write(buffer, 0, len);
			}

			// "输出"暂时结束(Socket没有关闭)
			s.shutdownOutput();

			// 来自于服务器的反馈
			try (BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()))) {
				String reply = reader.readLine();
				System.out.println("服务器的反馈:" + reply);
			}
		} catch (IOException e) {

			e.printStackTrace();
		}

	}
}

 

 

四. TCP 网络通讯不为人知的秘密

       当客户端连接到服务端后,实际上客户端也是通过一个端口和服务端进行通讯的,这个端口是TCP/IP来分配的,是不确定的,是随机的.

 

 

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值