Java的Socket网络编程基础知识入门教程
|
一、TCP/IP简介 TCP/IP协议族是互联网使用的协议,也可以用在独立的专用网络中。 IP协议使用IP地址来分发报文,但它是尽力而为的服务,报文可能丢失、乱序或者 不同的是,TCP协议会对IP层的错误进行修复,它通过握手消息在主机间建立连接, 关于IP地址,一台主机可以有多个网络接口,而一个接口又可以有多个地址。 A.回环地址:127.0.0.1,总是被分配给一个回环接口,主要用于测试。 B.私有地址:以10、192.168、172.(16-31)开头,用于私有网络。NAT设备转发报文 C.多播地址:第一个数字在224~239之间。 二、Socket基础 1.地址的获得
public static void main(String[] args) {
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface iface = interfaces.nextElement();
System.out.println("Interface: " + iface.getName());
Enumeration<InetAddress> addrList = iface.getInetAddresses();
if (!addrList.hasMoreElements())
System.out.println("No address");
while (addrList.hasMoreElements()) {
InetAddress address = addrList.nextElement();
System.out.println("Address: " + address.getHostAddress());
}
}
} catch (SocketException e) {
e.printStackTrace();
}
}
2.TCP实例程序 要注意一点,虽然在Client端只用了一个write()方法发送字符串,服务器端也可能从 TCPEchoClientTest.java
public static void main(String[] args) throws IOException {
String server = args[0];
byte[] data = args[1].getBytes();
int port = 7;
Socket socket = new Socket(server,port);
System.out.println("Connected to server...");
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
out.write(data);
int totalBytesRcvd = 0;
int bytesRcvd;
while (totalBytesRcvd < data.length) {
if ((bytesRcvd = in.read(data,totalBytesRcvd,data.length - totalBytesRcvd)) == -1)
throw new SocketException("Connection closed");
totalBytesRcvd += bytesRcvd;
}
System.out.println("Received: " + new String(data));
socket.close();
}
TCPEchoServerTest.java
private static final int BUFSIZE = 32;
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(7);
int recvMsgSize;
byte[] receiveBuf = new byte[BUFSIZE];
while (true) {
Socket socket = serverSocket.accept();
System.out.println("Handling client " +
" from remote " + socket.getRemoteSocketAddress() +
" at local " + socket.getLocalSocketAddress());
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
while ((recvMsgSize = in.read(receiveBuf)) != -1) {
out.write(receiveBuf,recvMsgSize);
}
socket.close();
}
}
注意new Socket时指定的是远端服务器监听的端口号而没有指定本地端口,因此将
为什么使用UDP协议?如果应用程序只交换少量的数据,TCP连接的建立阶段就至少 UDPEchoClientTest.java
public static void main(String[] args) throws IOException {
InetAddress serverAddress = InetAddress.getByName(args[0]);
byte[] bytesToSend = args[1].getBytes();
DatagramSocket socket = new DatagramSocket();
socket.setSoTimeout(3000);
DatagramPacket sendPacket = new DatagramPacket(
bytesToSend,bytesToSend.length,serverAddress,7);
DatagramPacket receivePacket = new DatagramPacket(
new byte[bytesToSend.length],bytesToSend.length);
// Packets may be lost,so we have to keep trying
int tries = 0;
boolean receivedResponse = false;
do {
socket.send(sendPacket);
try {
socket.receive(receivePacket);
if (!receivePacket.getAddress().equals(serverAddress))
throw new IOException("Receive from unknown source");
receivedResponse = true;
}
catch (IOException e) {
tries++;
System.out.println("Timeout,try again");
}
} while (!receivedResponse && tries < 5);
if (receivedResponse)
System.out.println("Received: " + new String(receivePacket.getData()));
else
System.out.println("No response");
socket.close();
}
UDPEchoServerTest.java
private static final int ECHOMAX = 255;
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(7);
DatagramPacket packet = new DatagramPacket(new byte[ECHOMAX],ECHOMAX);
while (true) {
socket.receive(packet);
System.out.println("Handling client at " + packet.getAddress());
socket.send(packet);
packet.setLength(ECHOMAX);
}
}
通过这个例子与之前TCP的实例进行比较,有如下区别: A.DatagramSocket在创建时不需要指定目的地址,因为UDP不需要建立连接,每个 B.如果像TCP一样在read()上阻塞等待,将可能永远阻塞在那里,因为UDP协议只是 C.UDP协议保留了消息的边界信息,每次receive()调用最多只能接收一次send()方法 D.一个UDP报文DatagramPacket能传输的最大数据是65507字节,超出部分的字节将 E.如果反复使用同一个DatagramPacket实例调用receive()方法,每次调用前都必须显式 (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 直接调用`clojure.lang.Compiler.compile`到AOT从Java编译C
- Java8中stream和functional interface的配合使用详解
- java – 获取TextView的高度
- java – 如何在返回多种类型的XML的URL上使用Spring RestTe
- Java Socket编程服务器响应客户端实例代码
- json解析时遇到英文双引号报错的解决方法
- IPUtil工具类,获取本机、远程IP的Java代码
- 如何强制java服务器只接受tls 1.2并拒绝tls 1.0和tls 1.1连
- java – 在使用它之前是否需要调用MessageDigest.reset()?
- Java、C++中子类对父类函数覆盖的可访问性缩小的区别介绍
