Java TCP编程详解

在解释TCP编程之前,我们先引入两个重要类:InetAddress和Socket

一、InetAddress类

与一般的Java类不同的是,InetAddress类没有构造方法,所以不能直接new出一个对象。一般我们都是通过InetAddress类的静态方法获得InetAddress的对象。最常用的主要有一下几个方法:

1、getLocalHost( )

获取本机InetAddress对象。对象中包含主机名和IP地址。

2、getByName( 主机名或ip)

获取指定主机名或IP的InetAddress对象。

3、getHostAddress()

获取当前InetAddress对象的IP地址

4、getHostName()

获取当前InetAddress对象的主机名(域名)

二、socket

        网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。在TCP通信中客户端和服务端各有一个Socket,是两台机器间通信的端点。事实上,网络通信就可两台设备的Socket之间的通信,数据在两个Socket间通过IO传输。

        客户端和服务端的IO流是使用Socket.getInputStream或Socket.getOutputStream通过Socket获取网络通道中的IO对象,如图:

三、TCP编程

1、使用字节流发送数据

客户端

1)新建一个Socket对象,参数是服务器的ip(或域名)和端口号。

2)新建OutPutStream对象out,把Socket . getOutputStream传递给新建的OutputStream。

3)与正常IO流一样发送文字、文件等(out . write)

4)发送完数据后一定要发送结束标志:Socket.shutdownOutput()。代表客户端异界发送结束了,服务器端可以关闭连接了,不用再等了。

5)关闭IO流和Socket。

6)客户端接受数据与服务端的步骤 (3)(4)相同。

服务端

1)新建SreverSocket对象,参数是客户端中设置的端口号。

2)Socket socket = serverSocket.accept();

新建Socket对象,接受客户端连接。这一步骤就是用来监听参数中的端口,如果没有客户端连接到端口中,程序会阻塞,直到有客户端连接为止。

3) 新建InputStream对象in,用Socket.getInputStream( ) 把套接字中的输入流传递给in。

4)与正常的IO一样接受数据。

5)服务端想发送数据步骤同客户端的(2)(3)(4)一样

5)关闭IO流、Socket和ServerSocket。

2、 使用字符流发送数据

大概思路

发送方式与1中的字节流大体相同,但是要使用字符流。因此要先用getOutputStream获取字节流对象,然后使用OutputWriter(参数是字节流对象)把字节流转换为字符流。

客户端

1)新建一个Socket对象,参数是服务器的ip(或域名)和端口号。

2)使用Socket.getOutputStream获取字节流对象,然后使用OutPutStreamWriter把字节流转换为字符流。把转换后的字符流对象作为参数放入处理流中。(处理流简单高效)

3)使用处理流发送数据

4)发送完数据后一定要发送一个换行:BufferedWriter.newLine();表示发送结束。随后flush一下,这样数据才能在流中显示

5)客户端想发送数据步骤同服务端的(2)(3)(4)一样

6)关闭IO流和Socket。

代码:

public static void main(String[] args) throws IOException {
    Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
    OutputStream out = socket.getOutputStream();
    out.write("hello,server".getBytes());
    System.out.println("发送成功");
    socket.shutdownOutput();
    InputStream inC = socket.getInputStream();
    int len;
    byte []bytes = new byte[1024];
    while ((len = inC.read(bytes)) != -1){
        System.out.println(new String(bytes,0,len));
    }
    out.close();
    inC.close();
    socket.close();
}

服务端

1)新建SreverSocket对象,参数是客户端中设置的端口号。

2)Socket socket = serverSocket.accept();

新建Socket对象,接受客户端连接。这一步骤就是用来监听参数中的端口,如果没有客户端连接到端口中,程序会阻塞,直到有客户端连接为止。

3) 新建InputStream对象in,用Socket.getInputStream( ) 把套接字中的输入流传递给in。

4)使用InputStreamReader把字节流对象in转换为字符流对象,再装入处理流中。(处理流简单高效)

5)与正常的IO一样接受数据。接受数据不用flush

6)服务端想发送数据步骤同客户端的(2)(3)(4)一样

7)关闭IO流、Socket和ServerSocket。

代码:

public static void main(String[] args) throws IOException {
    ServerSocket serverSocket = new ServerSocket(9999);
    System.out.println("服务端准备就绪,等待客户端连接......");
    Socket socket = serverSocket.accept();
    System.out.println("客户端连接成功!");
    InputStream in = socket.getInputStream();
    int len;
    byte []bytes = new byte[1024];
    while((len = in.read(bytes)) != -1){
        System.out.println(new String(bytes,0,len));
    }
    OutputStream outS = socket.getOutputStream();
    outS.write("helle,client".getBytes());
    socket.shutdownOutput();

    in.close();
    outS.close();
    socket.close();
    serverSocket.close();
}

3、TCP注意事项

当客户端连接服务器时,我们指定了服务器的监听端口。事实上,客户端在连接服务器时也会有一个端口分配给它,但这个端口不像服务器的监听端口那样由Socket指定,而是由TCP/IP协议随机发的,是不固定的。而在高并发的情况下,大量的客户端需要TCP/IP去随机分配端口,这样就导致了65535个端口不够用。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值