快速上手Java网络编程(二)基于TCP的套接字(Socket)通信

快速上手Java网络编程(二)基于TCP的套接字(Socket)通信


一、套接字概述

首先理解,计算机通信,这个通信更具体一点指的是什么?它事实上是主机的程序之间的通信。在网络通信中,我们使用IP地址来标识网络上的计算机,用端口号来标识一台主机上的各进程。因此,一个计算机上的进程想要与另一台计算机上的进程进行通信,不仅要知道它的IP地址,也要知道它所要通信进程的端口号,而网络套接字(Socket)正是IP和端口号的组合。

综上网络通信也可以看做是 套接字与套接字之间的通信

二、客户端套接字

上面的概述中,我们已经了解到,计算机进程的通信需要IP地址和端口号,这二者的组合即一个套接字。即一个进程想要发送消息给另一台计算机上的进程,它首先需要获取对应进程的套接字。下面就用Socket类创建一个套接字对象,使用Socket的构造方法:

try{
   
    Socket clientSocket = new Socket("127.0.0.1", 8080);
}catch(Exception e){
   
    System.out.println("socket对象创建失败");
}

由于建立套接字有可能发生错误,因此需要使用try-catch语句。通过上面的代码,就创建了一个指向IP地址为127.0.0.1,端口号为8080的套接字对象。

三、服务端套接字

根据上面的叙述,一个计算机进程只要有了网络上另一台计算机进程的套接字,那么这个进程就可以往这个套接字所代表的网络进程发送数据了,但同时,接收端还需要对套接字中的端口进行监听,才能获取发送端所发送的数据,这时就需要一个服务端套接字。服务端套接字的创建:

try{
   
    ServerSocket serverSocket = new ServerSocket(8080);
}catch(Exception e){
   }

此时,serverSocket就是一个代表了主机8080端口的服务端套接字,可以理解为这个服务端套接字在占用并监听着主机的8080端口。

四、通信的逻辑实现

下面如果没有一点计算机网络知识的人就会出现一个较难理解的地方。按照常理,客户端知道了服务端相应进程的套接字,服务端相应的进程也占用并监听了指定的端口,那两台主机间的进程应该可以实现通信了。A给B的信箱发送了一封信,B监听着信箱收到了A的消息,在收到信的同时B能够从信封上获取A的地址,这样双方都知道了对方对方信箱的地址,那么双方就可以通信了。但这种理论是基于UDP的通信,这种通信方式是不可靠的,因为你向对方的信箱发一封信,你是无法保证这封信在中途会不会被丢失的。而我们本次说的套接字的是基于TCP的通信。

TCP通信最显著的特点就是需要建立连接,即可以理解为专门在两个信箱间开辟专用的路了一条路用于通信,这种通信方式就会可靠地多(其实TCP协议是通过超时重传机制实现可靠传输的,这里不做赘述)。建立连接的过程如下:

//服务端
try{
   
    ServerSocket serverSocket = new ServerSocket(8080);
    Socket sc = serverSocket.accept();//再次创建的Socket对象为指代发送方的Socket对象
}catch(Exception e){
   }

如果serverSocket对象一直没有收到客户端呼叫的话,那么程序就会一直阻塞在

Socket sc = serverSocket.accept();

这个地方(可以通过设置超时时间,避免一直阻塞在此,这里略),而客户端的呼叫就发生在客户端创建套接字的时候。收到呼叫后

Socket sc = serverSocket.accept();

所创建的Socket对象为指代发送方的Socket对象。

五、通信的数据传输

OK,通过上面的叙述,我们已经知道了套接字通信的逻辑,那具体的数据是如何传输的呢?这里就涉及到了Java输入输出流的知识,通信的双方是通过数据流进行数据的传递。

通过上面的方式,客户端和服务端都已经可以获取对方的套接字,接下来双发只要获取数据流,通过数据流发送接收数据即可。

而数据流分为输入流输出流。此时,思考一下,发送方的输入流应该对应接收方的输出流发送方的输入流应该对应接收方的输出流,只有这样才能实现信息的传递。下面是一个实例:

客户端:

import java.io.*;
import java.net.*;

public class Client {
   
    public static void main(String[] args) {
   
        Socket socket;
        String question[] = {
   "question_1","question_2","question_2"};
        DataInputStream in;
        DataOutputStream out;
        try{
   
            socket = new Socket("127.0.0.1", 8080);
            in = new 
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值