二 了解socket编程
1 内部通信方式
2 socket
Socket与文件描述符一样,可以打开/读/写/关闭
在unix系统中,端口号0-1023预留给root和superuser
Socket类型
sock_stream 字节流通信
Socket_dcram 数据报文传输
Socket_ram 对信息传输进行高级控制 java不支持
3 tcp/ip udp/ip通信
数据报通信协议 如:udp无联接协议
流通信协议 tcp协议面向连接的协议
Udp与tcp
Udp需要发送本地描述符和接收方地址,数据报不能超过64kb,不能保证接收方按顺序接收,应用场景:客户服务器,程序需要广播,或希望开销较小
Tcp需要建立联接,应用场景:远程登录.FTP,
4 客户服务器通信
5 使用java进行socket进行编程
Socket和datagramSocket
数据流
inputStream
outputStream
Tcp socket
打开socket
创建数据输入流
创建数据输出流
关闭socket
示例代码如下:
/**
* Copyright (C) 2015
*
* FileName:TCPEchoClient.java
*
* Author:<a href="mailto:[email protected]">Retacn</a>
*
* CreateTime: 2015-1-15
*/
// Package Information
package cn.yue.test.net;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
/**
* tcp socket 客户端
*
* @version
*
* @Description:
*
* @author <a href="mailto:[email protected]">Retacn</a>
*
* @since 2015-1-15
*
*/
public class TCPEchoClient {
public static void main(String[] args) throws UnknownHostException, IOException {
// 控制台输入服务器地址,报文和端口
if ((args.length < 2) || (args.length > 3)) {
throw new IllegalArgumentException("(parameter(s):<server> <word> [<port>])");
}
String server = args[0];
byte[] data = args[1].getBytes();
int servPort = (args.length == 3) ? Integer.parseInt(args[3]) : 7;
// 创建socket
Socket socket = new Socket(server, servPort);
System.out.println("connecting to server ... sending echo string");
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 prematurely!");
}
totalBytesRcvd += bytesRcvd;
}
System.out.println("received: " + new String(data));
socket.close();
}
}
/**
* Copyright (C) 2015
*
* FileName:TCPEchoServer.java
*
* Author:<a href="mailto:[email protected]">Retacn</a>
*
* CreateTime: 2015-1-15
*/
// Package Information
package cn.yue.test.net;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
/**
* tcp socket 服务端程序
*
* @version
*
* @Description:
*
* @author <a href="mailto:[email protected]">Retacn</a>
*
* @since 2015-1-15
*
*/
public class TCPEchoServer {
// 用于接收数据的缓冲区
private static final int BUFSIZE = 32;
public static void main(String[] args) throws IOException {
// 从控制台接收端口号
if (args.length != 1) {
throw new IllegalArgumentException("parameter(s): <port>");
}
int servPort = Integer.parseInt(args[0]);
//
ServerSocket serverSocket = new ServerSocket(servPort);
int receiveMsgSize;
byte[] receiveBuf = new byte[BUFSIZE];
// 监听客户端请求
while (true) {
Socket clientSocket = serverSocket.accept();
SocketAddress clientAddress = clientSocket.getRemoteSocketAddress();
System.out.println("handing client as " + clientAddress);
InputStream in = clientSocket.getInputStream();
OutputStream out = clientSocket.getOutputStream();
while ((receiveMsgSize = in.read(receiveBuf)) != -1) {
// 向客户端写入
out.write(receiveBuf, 0, receiveMsgSize);
}
clientSocket.close();
}
}
}
Udp socket
创建一个datagramSocket实例
使用datagramSocket的send()和receive()来发送和接收数据
使用close关闭套接字
示例代码如下:
/**
* Copyright (C) 2015
*
* FileName:UDPEchoClient.java
*
* Author:<a href="mailto:[email protected]">Retacn</a>
*
* CreateTime: 2015-1-15
*/
// Package Information
package cn.yue.test.net;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
/**
* udp socket 客户端
*
* @version
*
* @Description:
*
* @author <a href="mailto:[email protected]">Retacn</a>
*
* @since 2015-1-15
*
*/
public class UDPEchoClient {
// 设置超时时间
private static final int TIMEOUT = 3000;
// 重复发送次数
private static final int MAXTRIES = 5;
public static void main(String[] args) throws IOException {
if ((args.length < 2) || (args.length > 3)) {
throw new IllegalArgumentException("parameter(s) <server> <word> [<port>]");
}
InetAddress serverAddress = InetAddress.getByName(args[0]);
byte[] bytesToSend = args[1].getBytes();
int serverPort = (args.length == 3) ? Integer.parseInt(args[2]) : 7;
//
DatagramSocket socket = new DatagramSocket(serverPort, serverAddress);
socket.setSoTimeout(TIMEOUT);
DatagramPacket sendpacket = new DatagramPacket(bytesToSend, bytesToSend.length, serverAddress, serverPort);
DatagramPacket receivePacket = new DatagramPacket(new byte[bytesToSend.length], bytesToSend.length);
// 发送包容易丢失,保持重发
int tries = 0;
boolean receivedResponse = false;
do {
socket.send(sendpacket);
try {
socket.receive(receivePacket);
// 检查数据源
if (!receivePacket.getAddress().equals(serverAddress)) {
throw new IOException("received packet from an unknow source");
}
receivedResponse = true;
} catch (InterruptedIOException e) {
tries += 1;
System.out.println("time out, " + (MAXTRIES - tries) + " more tries...");
}
} while ((!receivedResponse) && (tries < MAXTRIES));
if (receivedResponse) {
System.out.println("received: " + new String(receivePacket.getData()));
} else {
System.out.println("no response -- qiving up.");
}
socket.close();
}
}
/**
* Copyright (C) 2015
*
* FileName:UDPEchoServer.java
*
* Author:<a href="mailto:[email protected]">Retacn</a>
*
* CreateTime: 2015-1-15
*/
// Package Information
package cn.yue.test.net;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* udp socket 服务器端
*
* @version
*
* @Description:
*
* @author <a href="mailto:[email protected]">Retacn</a>
*
* @since 2015-1-15
*
*/
public class UDPEchoServer {
private static final int ECHOMAX = 255;
public static void main(String[] args) throws IOException {
// 控制台输入端口号
if (args.length != 1) {
throw new IllegalArgumentException("parameter(s) <port>");
}
int serverPort = Integer.parseInt(args[0]);
DatagramSocket socket = new DatagramSocket(serverPort);
DatagramPacket packet = new DatagramPacket(new byte[ECHOMAX], ECHOMAX);
while (true) {
socket.receive(packet);
System.out.println("hading client an " + packet.getAddress() + " on port " + packet.getPort());
socket.send(packet);
packet.setLength(ECHOMAX);
}
}
}
多点传送socket
MulticastSocket 此类应用于客户端,用监听服务器广播到多个客户的包
使用多点传送ip要使用基于upd协议
6 greetings服务器实例
服务器程序
客户程序
以上两个程序同5所示代码
7 解析internate地址
getName //取得机器的字符名
getIp //取得机器的ip地址
nsLookUp //根据主机名找ip,反之也可
IPtoName //ip地址转换