网络编程的底层是IO,通过IO将一台计算机中的数据发送到另一台计算机中。发送的时候,要知道接受方的地址,该地址即为IP地址。知道IP地址后即可进行发送。A向B发消息,消息是发过去了,但是B要怎样接受呢?因此定义了端口,B监听了A所使用的端口。A发的消息中含有端口号,当B接受到消息时,知道了端口号。B就知道用什么程序来读取消息。
- 获取IP地址对象的几种方式:
- 获得本机的ip用InetAddress. getLocalHost方法返回ip对象
- 通过网站的名称
- 通过字符串式的ip地址
- 通过byte类型的数组
public class Maintest {
public static void main(String[] args)throws Exception{
InetAddress ip1=InetAddress.getLocalHost();
System.out.println(ip1);
InetAddress ip2=InetAddress.getByName("www.baidu.com");
System.out.println(ip2);
InetAddress ip3=InetAddress.getByName("183.232.231.173");//百度的域名
System.out.println(ip3);
InetAddress ip4=InetAddress.getByAddress(new byte[]{(byte)192,(byte)168,0,1});
System.out.println(ip4);
}
}
输出结果:
DESKTOP-24DBAMN/192.168.92.1
www.baidu.com/183.232.231.173
/183.232.231.173
/192.168.0.1
2.Socket:Socket是计算机进行数据交互时的一个接口。一台计算机和另外一台计算机进行对话时socket就会建立一个连接通道。通过通道进行数据交换。
ServerSocket:用于建立等待来自客户端访问的“服务器”,Socket用于表示网络之间的通信。
要建立一个通信应用,首先要建立一个服务端的应用。ServerSocket专门用于 建立服务端的Socket应用,它不主动连接,而是打开一个端口等待客户端连接。
一般情况下,将ServerSocket的OutputStream当做是客户端Socket的InputStream,而将客户端的OutputStream当做是服务端Socket的InputStream。
ServerSocket和Socket的双向通信:服务器要能收到客户端发来的消息,服务端要能给客户端发送消息。因此,服务端要有收消息和发消息两个线程;客户端也要有这两个线程。该程序由一下四部分组成:
(1)服务端:
public class Server {
public static void main(String[] args) throws Exception{
ServerSocket ss=new ServerSocket(6666);//监听6666端口
System.out.println("这里是服务器");
Socket socket=ss.accept();//等待客户端连接,否则阻塞。连接后得到socket对象。
InputStream inputStream=socket.getInputStream();
OutputStream outputStream=socket.getOutputStream();
//接收消息的线程,线程名字表示当前线程所在的位置
Thread receiveThread=new Thread(new Receive(inputStream),"serverReceive");
receiveThread.start();
//发送消息的线程
Thread sendThread=new Thread(new Send(outputStream),"serverSend");
sendThread.start();
}
}
(2)客户端:
public class client {
public static void main(String[] args) throws Exception {
InetAddress ip=InetAddress.getLocalHost();
Socket socket=new Socket(ip,6666);
System.out.println("这里是客户端");
OutputStream outputStream=socket.getOutputStream();
InputStream inputStream=socket.getInputStream();
//发送的线程
Thread sendThread=new Thread(new Send(outputStream),"clientSend");
sendThread.start();
//接收线程
Thread receiveThread=new Thread(new Receive(inputStream),"clientReceive");
receiveThread.start();
}
}
(3)收消息的线程类:
public class Receive implements Runnable {
private InputStream inputStream=null;
public Receive() {
}
public Receive(InputStream inputStream) {
this.inputStream = inputStream;
}
@Override public void run() {
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
String string=null;
try {
while(null!=(string=bufferedReader.readLine()))
{
String from=Thread.currentThread().getName().contains("client")?"Server:":"Client:";
string=from+string;
System.out.println(string);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
(4)发送消息的线程:
public class Send implements Runnable{
private OutputStream outputStream=null;
public Send() {
}
public Send(OutputStream outputStream) {
this.outputStream = outputStream;
}
@Override public void run() {
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));
PrintStream printStream=new PrintStream(outputStream);
String string=null;
try {
while(null!=(string=bufferedReader.readLine()))
{
printStream.println(string);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果(先启动服务端,后启动客户端):
客户端:
这里是客户端
你好服务器,我是客户端。
Server:你好客户端,我是服务器
服务端:
这里是服务器
Client:你好服务器,我是客户端。
你好客户端,我是服务器