udp socket java_基于TCP和UDP的Socket实现(JAVA)

本文介绍如何用Java实现Socket编程。首先介绍Java针对Socket编程提供的类,以及它们之间的关系。然后分别针对TCP和UDP两种传输层协议实现Socket编程。

1 Java中的Socket编程接口介绍

Java为Socket编程封装了几个重要的类。

1.1 Socket类

Socket类实现了一个客户端socket,作为两台机器通信的终端,默认采用的传输层协议为TCP,是一个可靠传输的协议。Socket类除了构造函数返回一个socket外,还提供了connect, getOutputStream, getInputStream和close方法。connect方法用于请求一个socket连接,getOutputStream用于获得写socket的输出流,getInputStream用于获得读socket的输入流,close方法用于关闭一个流。

1.2 DatagramSocket类

DatagramSocket类实现了一个发送和接收数据报的socket,传输层协议使用UDP,不能保证数据报的可靠传输。DataGramSocket主要有send, receive和close三个方法。send用于发送一个数据报,Java提供了DatagramPacket对象用来表达一个数据报。receive用于接收一个数据报,调用该方法后,一直阻塞接收到直到数据报或者超时。close是关闭一个socket。

1.3 ServerSocket类

ServerSocket类实现了一个服务器socket,一个服务器socket等待客户端网络请求,然后基于这些请求执行操作,并返回给请求者一个结果。ServerSocket提供了bind、accept和close三个方法。bind方法为ServerSocket绑定一个IP地址和端口,并开始监听该端口。accept方法为ServerSocket接受请求并返回一个Socket对象,accept方法调用后,将一直阻塞直到有请求到达。close方法关闭一个ServerSocket对象。

1.4 SocketAddress

SocketAddress提供了一个socket地址,不关心传输层协议。这是一个虚类,由子类来具体实现功能、绑定传输协议。它提供了一个不可变的对象,被socket用来绑定、连接或者返回数值。

1.5 InetSocketAddress

InetSocketAddress实现了IP地址的SocketAddress,也就是有IP地址和端口号表达Socket地址。如果不制定具体的IP地址和端口号,那么IP地址默认为本机地址,端口号随机选择一个。

1.6. DatagramPacket

DatagramSocket是面向数据报socket通信的一个可选通道。数据报通道不是对网络数据报socket通信的完全抽象。socket通信的控制由DatagramSocket对象实现。DatagramPacket需要与DatagramSocket配合使用才能完成基于数据报的socket通信。

860082ab5d6772e2aa4da49ddbbd18d5.png

2. 基于TCP的Socket编程

上面描述了Java对Socket编程提供的接口,本节介绍如何实现一个基于TCP连接的Socket通信。

下面例子是Server端等待从Client端接收一条消息,然后再给客户端发送一个消息。

服务器端首先实例化ServerSocket对象,然后为其绑定一个本机地址,并开始监听。一直阻塞状态下等待客户端请求,当获得客户端连接请求后,返回一个socket对象。然后用这个socket接收一条消息,并发送一条消息。代码如下:

packageserver.socket.java;importjava.io.IOException;importjava.io.PrintWriter;importjava.net.InetAddress;importjava.net.InetSocketAddress;importjava.net.ServerSocket;importjava.net.Socket;importjava.net.SocketAddress;public classSocketTcp {static private String TAG = "SocketTcp: ";public static voidmain(String[] args){try{

ServerSocket server= newServerSocket();

SocketAddress address= new InetSocketAddress(InetAddress.getLocalHost(), 10001);

server.bind(address);

System.out.println("==waiting for being connected...");

Socket client=server.accept();

System.out.println("==connected with " +client.getRemoteSocketAddress() );

PrintWriter socketOut= newPrintWriter(client.getOutputStream());

System.out.println("==waiting message from client...");byte buf[] = new byte[1024];if ( client.getInputStream().read(buf) > 0) {

System.out.println("Receive Message: " + newString(buf));

}

System.out.println("==sending message to client...");

String sendStr= "This is the message for client.";

socketOut.write(sendStr);

socketOut.flush();

socketOut.close();

client.close();

server.close();

}catch(IOException e) {

System.out.println(TAG+e.getMessage());

e.printStackTrace();

}

}

}

客户端首先实例化一个socket对象,用这个对象连接服务器端。连接成功后,发送一条消息,然后等待接收一条消息。代码如下:

packageclient.socket.java;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.PrintWriter;importjava.net.InetAddress;importjava.net.InetSocketAddress;importjava.net.Socket;importjava.net.SocketAddress;public classSocketTcp {static private String TAG = "SocketTcp: ";public static voidmain(String[] args){try{final Socket socket = newSocket();

SocketAddress address= new InetSocketAddress(InetAddress.getLocalHost(), 10001);

System.out.println("==connecting to server ...");

socket.connect(address);

PrintWriter socketOut= newPrintWriter(socket.getOutputStream());

BufferedReader socketIn= newBufferedReader(newInputStreamReader(socket.getInputStream()) );

String sendStr= "This is the message for server.";

System.out.println("==sending message to server ...");

socketOut.write(sendStr);

socketOut.flush();

System.out.println("==waiting message from server ...");

String receiveStr=socketIn.readLine();

System.out.println("Receive Message: " +receiveStr);

socketOut.close();

socketIn.close();

socket.close();

}catch(IOException e) {

System.out.println(TAG+e.getMessage());

e.printStackTrace();

}finally{

}

}

}

服务器端运行结果:

==waiting forbeing connected...==connected with /172.26.176.69:53912

==waiting message from client...

Receive Message: This is the messagefor server.

客户端运行结果:

==connecting to server ...==sending message to server ...==waiting message from server ...

Receive Message: This is the messagefor client.

3 基于UDP的Socket编程示例

基于UDP的Socket编程与基于TCP的socket编程稍有不同,socket server和client都用DatagramSocket实现。

下面例子是Server端等待从Client端接收一条消息,然后再给客户端发送一个消息。

服务器端首先实例化DatagramSocket对象,然后为其绑定一个本机地址,并开始监听。一直阻塞状态下等待从客户端接收数据报。然后从数据报中获取数据报的源地址,然后用这个源地址作为目的地址打包一个数据报,然后发送出去。代码如下:

packageserver.socket.java;importjava.io.IOException;importjava.net.DatagramPacket;importjava.net.DatagramSocket;importjava.net.InetAddress;importjava.net.InetSocketAddress;importjava.net.SocketAddress;importjava.net.SocketException;importjava.net.UnknownHostException;public classSocketUdp {final private static String TAG = "SocketUdp: ";public static voidmain(String args[]) {

DatagramSocket socket= null;

DatagramPacket datapacket= null;

InetSocketAddress address= null;try{

address= new InetSocketAddress(InetAddress.getLocalHost(), 7778);

socket= newDatagramSocket(address);//socket.bind(address);

byte buf[] = new byte[1024];

datapacket= newDatagramPacket(buf, buf.length);

System.out.println("==block for receive messages...");

socket.receive(datapacket);

buf=datapacket.getData();

InetAddress addr=datapacket.getAddress();int port =datapacket.getPort();

System.out.println("Message Content: " + newString(buf) );

System.out.println("Receive From " + addr + ":" +port);

SocketAddress toAddress=datapacket.getSocketAddress();

String sendStr= "I'm Server, this is the message for client.";

buf=sendStr.getBytes();

datapacket= newDatagramPacket(buf, buf.length);

datapacket.setSocketAddress(toAddress);

socket.send(datapacket);

System.out.println("==message sended");

}catch(UnknownHostException e) {

System.out.println(TAG+e.getMessage());

e.printStackTrace();

}catch(SocketException e) {

System.out.println(TAG+e.getMessage());

e.printStackTrace();

}catch(IOException e) {

System.out.println(TAG+e.getMessage());

e.printStackTrace();

}

}

}

客户端首先实例化一个DatagramSocket对象。利用服务器地址和端口号作为目的地址打包一个数据报,并发送。然后等待从服务器回复的数据报。代码如下:

packageclient.socket.java;importjava.io.IOException;importjava.net.DatagramPacket;importjava.net.DatagramSocket;importjava.net.InetAddress;importjava.net.InetSocketAddress;importjava.net.SocketException;importjava.net.UnknownHostException;public classSocketUdp {final private static String TAG = "SocketUdp: ";public static voidmain(String args[]) {try{

DatagramSocket getSocket= newDatagramSocket();

DatagramPacket datapacket= null;

InetSocketAddress toAddress= new InetSocketAddress(InetAddress.getLocalHost(), 7778);

String sendStr= "I'm client, this is the message for server.";byte buf[] =sendStr.getBytes();

datapacket= newDatagramPacket(buf, buf.length);

datapacket.setSocketAddress(toAddress);

getSocket.send(datapacket);

System.out.println("==message sended");

System.out.println("==block for receive messages...");

getSocket.receive(datapacket);

buf=datapacket.getData();

System.out.println("Message Content: " + newString(buf));

}catch(SocketException e) {

System.out.println(TAG+e.getMessage());

e.printStackTrace();

}catch(UnknownHostException e) {

System.out.println(TAG+e.getMessage());

e.printStackTrace();

}catch(IOException e) {

System.out.println(TAG+e.getMessage());

e.printStackTrace();

}

}

}

服务器端运行结果:

==block forreceive messages...

Message Content: I'm client, this is the message for server.

客户端运行结果:

==message sended==block forreceive messages...

Message Content: I'm Server, this is the message for client.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值