获取主机名和IP
InetAddress localIPAdress=InetAddress.getLocalHost();
System.out.println("IP:"+localIPAdress.getHostAddress());
System.out.println("主机名:"+localIPAdress.getHostName());
什么是Socket?
在开发网络程序的时候,会遇到Socket这个概念。Socket是一个抽象概率,一个应用程序通过一个Socket来建立一个远程接受,而Socket内部通过Tcp/IP协议把数据传输到网络。
┌───────────┐ ┌───────────┐
│Application│ │Application│
├───────────┤ ├───────────┤
│ Socket │ │ Socket │
├───────────┤ ├───────────┤
│ TCP │ │ TCP │
├───────────┤ ┌──────┐ ┌──────┐ ├───────────┤
│ IP │<────>│Router│<─────>│Router│<────>│ IP │
└───────────┘ └──────┘ └──────┘ └───────────┘
Java提供的几个Socket相关的类就封装了操作系统提供的接口:ServerSocket类,Socket类。
一个Socket就是由IP地址和端口号(范围是0~65535)组成,可以把Socket简单理解成IP地址加端口号.端口号总是由操作系统分配,它是一个0~65535之间的数字,其中,小于1024的端口属于特权端口,需要管理员权限,大于1024的端口可以由任意用户的应用程序打开.
使用Socket进行网络编程时,本质上就是两个进程之间的网络通信.其中一个进程必须充当服务器端,它会主动监听某个指定的端口,另一个进程必须充当客户端,它必须主动连接服务器的IP地址和指定端口。如果连接成功,服务器端和客户端就成功地建立一个TCP连接,双方后续就可以随时发送和接收数据。
因此,当Socket连接成功地在服务器和客户端之间建立后;
1.对服务器端来说,它的Socket是指定的IP地址和指定的端口号;
2.对客户端来说,它的Socket是它所在计算机的IP地址和指定的端口号;
3.对客户端来说,它的Socket是它所在计算机的IP地址和一个由操作系统分配的随机端口号。
服务器端
要使用Socket编程,我们首先编写服务器端程序.Java标准库提供了ServerSocket来实现对指定IP和指定端口的监听。ServerSocket的典型实现代码如下:
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(6666); // 监听指定端口
System.out.println("server is running...");
while (true) {
Socket sock = ss.accept();
// 使用Socket流进行网络通信
// ...
System.out.println("connected from " + sock.getRemoteSocketAddress());
}
}
}
服务器端通过下述代码,在指定端口6666监听.这里我们没有指定IP地址,表示在计算机的所有网络接口上进行监听。
ServerSocket ss = new ServerSocket(6666);
如果ServerSocket监听成功,我们就使用一个无限循环来处理客户端的连接,注意到代码ss.accept()表示每当有新的客户端连接进来后,就会返回一个Socket实例,这个Socket实例就是用来和刚连接的客户端进行通信的。
while (true) {
Socket sock = ss.accept();
System.out.println("connected from " + sock.getRemoteSocketAddress());
}
客户端
通过端口号和ip连接到服务器端.如果连接成功,将返回一个Socket实例.
Socket sock = new Socket("localhost", 6666);
案例
使用TCP实现图片上传
客户端
try (Socket client = new Socket("192.168.254.172",8848);
OutputStream out=client.getOutputStream();
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("c:\\test\\img\\gg.jpg"))) {
byte[] buff=new byte[1024];
int len=-1;
while((len=bis.read(buff))!=-1) {
out.write(buff);
}
client.shutdownOutput();
try(BufferedReader reader=new BufferedReader(new InputStreamReader(client.getInputStream()))){
String reply=reader.readLine();
System.out.println("服务器的反馈:"+reply);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
服务器端
try (ServerSocket server = new ServerSocket(8848)) {
while (true) {
Socket client = server.accept();
InetAddress clientNetAddress = client.getInetAddress();
System.out.println("客户端" + clientNetAddress.getHostAddress() + "开始连接");
String imageName = clientNetAddress.getHostAddress().replaceAll("\\.", "-") + ".jpg";
try (InputStream in = client.getInputStream();
BufferedInputStream bis = new BufferedInputStream(in);
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("c:\\test\\excel\\" + imageName))) {
byte[] buff = new byte[1024];
int len = -1;
while ((len = bis.read(buff)) != -1) {
bos.write(buff, 0, len);
}
System.out.println("图片读取完毕!");
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()))) {
writer.write("upload success");
writer.newLine();
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Socket流
Java标准库使用InputStream和OutputStream来封装Socket的数据流.
// 用于读取网络数据:
InputStream in = sock.getInputStream();
// 用于写入网络数据:
OutputStream out = sock.getOutputStream();