Java_套接字

套接字

①网络通信使用IP地址标识Internet上的计算机,使用端口号标识服务器上的进程(程序)

②服务器上的每个程序都占用一个端口号,用于找到程序与程序交互信息

③端口号被规定为一个16位的0~65535之间的整数,其中**,0-1023被预先定义的服务通信占用**(如telnet占用端口23,http占用端口80等),除非我们需要访问这些特定服务,否则,就应该使用1024–65535这些端口中的某一个进行通信,以免发生端口冲突。

④当两个程序需要通讯时,它们可以通过使用socket类建立套接字对象并连接在一起(端口号与IP地址的组合得出一个网络套接字)

⑤以下步骤在两台计算机之间使用套接字建立TCP连接时会出现:
1️⃣服务器实例化一个 ServerSocket 对象,表示通过服务器上的端口通信。
2️⃣服务器调用 ServerSocket 类的 accept() 方法,该方法将一直等待,直到客户端连接到服务器上给定的端口。
3️⃣服务器正在等待时,一个客户端实例化一个 Socket 对象,指定服务器名称和端口号来请求连接。
4️⃣Socket 类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个 Socket 对象能够与服务器进行通信。
5️⃣在服务器端,accept() 方法返回服务器上一个新的 socket 引用,该 socket 连接到客户端的 socket。
连接建立后,通过使用 I/O 流在进行通信,每一个socket都有一个输出流和一个输入流,客户端的输出流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。

TCP 是一个双向的通信协议,因此数据可以通过两个数据流在同一时间发送。

客户端套接字

java.net.Socket 类代表客户端和服务器都用来互相沟通的套接字。客户端要获取一个 Socket 对象通过实例化 ,而 服务器获得一个 Socket 对象则通过 accept() 方法的返回值。
客户端的程序使用Socket类建立负责连接到服务器的套接字对象
②Socket的构造方法是Socket(String host,int port),参数host是服务器的IP地址,port是一个端口号。建立套接字对象可能会发生IOException异常:

try{
	Socket mysocket = new Socket("http://192.168.0.78",2010);
}catch(IOException e){
}

当套接字对象mysocket建立后,mysocket可以使用方法getInputStream()获得一个输入流,这个输入流的源和服务器端的一个输入流的目的地刚好相同,因此客户端用输入流可以读取服务器写入到输出流中的数据
mysocket使用方法getOutputStream()获得一个输出流,这个输出流的目的地和服务器端的一个输入流的源刚好相同,因此服务器用输入流可以读取客户写入到输出流中的数据

Socket类方法

在这里插入图片描述
当 Socket 构造方法返回,并没有简单的实例化了一个 Socket 对象,它实际上会尝试连接到指定的服务器和端口。
注意客户端和服务器端都有一个 Socket 对象,所以无论客户端还是服务端都能够调用这些方法。
在这里插入图片描述

ServerSocket对象与服务器端套接字

ServerSocket 类方法

服务器应用程序通过使用 java.net.ServerSocket 类以获取一个端口,并且侦听客户端请求
在这里插入图片描述
创建非绑定服务器套接字。 如果 ServerSocket 构造方法没有抛出异常,就意味着你的应用程序已经成功绑定到指定的端口,并且侦听客户端请求
在这里插入图片描述

InetAddress类的方法

这个类表示互联网协议(IP)地址。
在这里插入图片描述

使用流程

①客户负责建立连接到服务器的套接字对象,即客户负责呼叫。为了能使客户成功地连接到服务器,服务器必须建立一个ServerSocket对象,该对象通过将客户端的套接字对象和服务器端的一个套接字对象连接起来,从而达到连接的目的
②ServerSocket的构造方法是ServerSocket(int port),port是一个端口号。port必须和客户呼叫的端口号相同。建立ServerSocket对象可能发生IOException异常:

try{
	ServerSocket serverForClient = new ServerSocket(2010);
}catch(IOException e){
}

例如:2010端口已被占用时,就会发生IOException异常。
③当服务器的ServerSocket对象serverForClient建立后,就可以使用方法**accept()**将客户的套接字和服务器端的套接字连接起来。

try{
	Socket sc = serverForClient.accept();
}catch(IOException e){
}

所谓"接收"客户的套接字连接是指服务器端的ServerSocket对象:serverForClient调用accept()方法会返回一个与客户端Socket对象相连接的Socket对象sc
⑤驻留在服务器端的这个Socket对象sc调用getOutputStream()获得的输出流,将指向客户端Socket对象mysocket调用getInputStream()获得的那个输入流,即服务器端的输出流的目的地和客户端输入流的源刚好相同 ;同样,服务器端的这个Socket对象sc调用getInputStream()获得的输入流,将指向客户端Socket对象mysocket调用getOutputStream()获得的那个输出流,即服务器端的输入流的源和客户端输出流的源刚好相同
在这里插入图片描述
accept()方法也会阻塞线程的继续执行,直到接收到客户的呼叫。也就是说,如果没有客户呼叫服务器,那么下述代码中的System.out.println(“hello”)不会被执行:

try{
	Socket sc = server_socket.accept();
	System.out.println("hello");
}catch(IOException e){
}

连接建立后,服务器端的套接字对象调用getInetAddress()方法可以获取一个InetAddress对象,该对象含有客户端的IP地址和域名,同样,客户端的套接字对象调用getInputStream()方法可以获取一个InetAddress对象,该对象含有服务器端的IP地址和域名。
双方通信完毕后,套接字应使用close()方法关闭套接字连接
ServerSocket对象可以调用setTimeout(int timeout)方法设置超时值(ms),timeout是一个正值,当ServerSocket对象调用accept方法堵塞的时间一旦超过timeout时,将触发SocketTimeoutException。
在这里插入图片描述
在这里插入图片描述
Client.java

package SocketClass;

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

public class Client {
    public static void main(String []args){
        String []mess = {"1+1在什么情况下不等于2","狗为什么不生跳蚤","什么东西能看、能吃、能坐"};
        Socket mysocket;
        DataInputStream in = null;
        DataOutputStream out = null;
        try{
            mysocket = new Socket("127.0.0.1",2010);
            in = new DataInputStream(mysocket.getInputStream());
            out = new DataOutputStream(mysocket.getOutputStream());
            for(int i = 0;i < mess.length;i++){
                out.writeUTF(mess[i]);
                String s = in.readUTF();//in读取信息,堵塞状态
                System.out.println("客户收到服务器的回答"+s);
                Thread.sleep(500);
            }
        }catch (Exception e){
            System.out.println("服务器已断开"+e);
        }
    }
}

Server.java

package SocketClass;

import java.io.*;
import java.net.*;
public class Server {
    public static void main(String args[]){
        String []answer = {"在算错的情况下","狗只能生狗","电视、面包、沙发"};
        ServerSocket serverForClient = null;
        Socket socketOnServer = null;
        DataOutputStream out = null;
        DataInputStream in = null;
        try{
            serverForClient = new ServerSocket(2010);
        }catch (Exception e){
            System.out.println(e);
        }

        try{
            System.out.println("等待客户呼叫");
            socketOnServer = serverForClient.accept();//堵塞状态,除非有客户呼叫
            out = new DataOutputStream(socketOnServer.getOutputStream());
            in = new DataInputStream(socketOnServer.getInputStream());
            for(int i = 0;i<answer.length;i++){
                String s = in.readUTF();//in读取信息,堵塞状态
                System.out.println("服务器收到客户的提问:"+s);
                out.writeUTF(answer[i]);
                Thread.sleep(500);
            }
        }catch (Exception e){
            System.out.println("客户已断开"+e);
        }
    }
}

使用多线程技术

①需要注意的是,从套接字连接中读取数据与从文件中读取数据有着很大的不同。尽管二者都是输入流,但从文件中读取数据时,所有的数据都已经在文件中了,而使用套接字连接时,可能在另一端数据发送出来之前,就已经开始试着读取了,这时就会堵塞本线程,直到该读取方法成功读取到信息,本线程才能继续执行后序的操作。因此,服务器端接收到一个客户的套接字后,就应该启动一个专门为该客户服务的线程。
在这里插入图片描述
可以使用Socket类的不带参数的构造方法Socket()创建一个套接字对象,该对象再调用

public void connect(SocketAddress endpoint) throws IOException

请求和参数SocketAddress指定地址的服务器端的套接字建立连接
为了使用connect()方法,可以使用SocketAddress的子类InetSocketAddress创建一个对象,InetSocketAddress的构造方法是:
public InetSocketAddress(InetAddress addr ,int port)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值