java tcp ip网络编程(二) 套接字的基本使用

时间:2022-08-16 08:25:00

##基本套接字的使用

linux系统把网络io抽象成socket,对网络的编程就是对socket的编程。

java把套接字抽象成类似的类

InetAddress SocketAddress 识别java应用程序如何识别网络主机
客户端Socket类 ServerSocket类
UDP类 DatagramSocket

获取用户的网卡和对应的ip信息

通过host获取对应的网络地址
```
Enumeration<NetworkInterface> networkInterfaceEnumeration =
NetworkInterface.getNetworkInterfaces();

if(networkInterfaceEnumeration == null){
System.out.println("no interfacle");
}else{
while (networkInterfaceEnumeration.hasMoreElements()){
NetworkInterface networkInterface = networkInterfaceEnumeration.nextElement();
Enumeration<InetAddress> address = networkInterface.getInetAddresses();
if(!address.hasMoreElements()){
System.out.println("it is not address");
}
System.out.println("networkInterface:"+networkInterface.getName());
while (address.hasMoreElements()){
InetAddress address1 = address.nextElement();
System.out.println(
address1 instanceof Inet4Address ?"ipv4":"ipv6"
);
System.out.println(address1.getHostAddress());
}
System.out.println("####");
}

}

System.out.println("host xxx"+args.length);
String[] arr = new String[1];
arr[0] = "weibo.cn";
for (String host : arr){
System.out.println(host+":");
InetAddress[] inetAddresses = InetAddress.getAllByName(host);

for(InetAddress inet: inetAddresses){
System.out.println(inet.getHostName()+":"+inet.getHostAddress());
System.out.println("toString:"+inet.toString());
System.out.println("caninical:"+inet.getCanonicalHostName());
}
}
```

java提供了TCP套接字

Socket,ServerSocket

客户端

```
if(args.length != 3){
throw new Exception("arg lengh is not right!");
}

String host = args[0];
byte[] data = args[1].getBytes();
int port = Integer.parseInt(args[2]);

Socket socket = new Socket(host, port);
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
outputStream.write(data);
System.out.println("write data"+data);
int totalRecived = 0;
int recived;
while (totalRecived < data.length){

if((recived = inputStream.read(data,
totalRecived, data.length-totalRecived)) == -1){
throw new IllegalStateException("IllegalStateException");
}
System.out.println("totalRecived:"+totalRecived);
totalRecived += recived;
}

System.out.println("received:"+ new String(data));
socket.close();
```

服务端
```
if(args.length != 1){
throw new Exception("arg lengh is not right!");
}

ServerSocket serverSocket = new ServerSocket(
Integer.parseInt(args[0]));

int temp = 0;
byte[] data = new byte[buffer];
while (true){

Socket socket = serverSocket.accept();
SocketAddress socketAddress = socket.getRemoteSocketAddress();
System.out.println("client address"+socketAddress.toString());
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
while ((temp = in.read(data)) != -1){
out.write(data,0, temp);
}
socket.close();
}

```

udp协议的主要功能

1 在ip地址上增加了端口
2 对传输过程中可能产生的数据错误进行了检测,并抛弃了已经损坏的数据

udp的特定

1 设置消息边界
2 应用程序必须处理丢失和重排功能

java提供的UDP套接字

DatagramSocket
DatagramPacket

服务端
```
DatagramSocket datagramSocket = new DatagramSocket(port);

DatagramPacket packet = new DatagramPacket(new byte[MAX_LENGTH],
MAX_LENGTH);

while (true){
datagramSocket.receive(packet);
System.out.println("client "+packet.getAddress().getHostAddress()+" "+
packet.getPort());
datagramSocket.send(packet);
packet.setLength(MAX_LENGTH);
}
```

客户端
```
InetAddress address = InetAddress.getByName(args[0]);
byte[]data = args[1].getBytes();
int port = Integer.parseInt(args[2]);
DatagramPacket sendPacket = new DatagramPacket(
data,data.length,address,port
);

DatagramSocket datagramSocket = new DatagramSocket();
datagramSocket.setSoTimeout(timeout);

DatagramPacket receive = new DatagramPacket(
new byte[data.length],data.length
);

boolean receivedResponse = false;
int tries = 0;
do{
datagramSocket.send(sendPacket);
try{
datagramSocket.receive(receive);
if(!receive.getAddress().equals(address)){
System.out.println("receive unknow host");
}
receivedResponse = true;
}catch (InterruptedIOException e){
tries++;
System.out.println("retry times :"+tries);
}

}while (tries < times && !receivedResponse);

if(receivedResponse){
System.out.println("Received:" + new String(receive.getData()));
}

datagramSocket.close();
```