InetAddress ip = InetAddress.getByName(host);//host能够是计算机名字也能够是IP地址如127.0.0.1
复制代码
在程序中使用scoket进行通讯,使用socket通讯须要指定IP、端口、协议(UDP、TCP);数据发送分为两步:一、第一步是监听(等待数据发送过来),用来接收数据,需指定监听的端口;二、第二部是发送(须要指定发送到哪一个计算机:IP地址,该计算机的哪一个程序:Port号)。编程
socket中分为发送端和接收端:发送端通常为客户端,接收端通常为服务端。数组
通常有多个客户端,一个服务端。bash
UDP协议无需创建链接,直接向接收端发送数据报,不用考虑对方是否接收到数据报,只须要向接收方发送就行,至于接收方有没有接收到发送端不用管。因此使用UDP协议进行网络数据传输是不可靠的,可是速度快!微信
使用UDP协议开发发送端: 用DatagramSocket发送数据:网络
DatagramSocket ds = new DatagramSocket();//socket套接字
复制代码
用DatagramPacket做为包裹(发送的数据内容):socket
byte[] buf = "你好,我想给你发送数据!".getBytes();//字节数组
int length = buf.length;//发送的长度
InetAddress address = InetAddress.getByName("127.0.0.1");//指定接收端的IP地址
int port = 7878;//指定接收端的监听端口号,与接收端对应
DatagramPacket dp = new DatagramPacket(buf, length, address, port);//待发送的包裹
复制代码
send()发送数据,close()释放资源。ide
ds.send(dp);//发送1次
//ds.send(dp);//发送2次
...
//ds.send(dp);//发送n次
ds.close();//发送完毕,释放资源
复制代码
举个栗子🌰:ui
//UDP发送端
public class Demo2_UDP_Send {
public static void main(String[] args) throws Exception {
DatagramSocket ds = new DatagramSocket();//socket套接字
byte[] buf = "你好,我想给你发送数据!".getBytes();//字节数组
int length = buf.length;//发送数据的长度
InetAddress address = InetAddress.getByName("127.0.0.1");//指定接收端的IP地址
int port = 7878;//指定接收端的端口号
DatagramPacket dp = new DatagramPacket(buf, length, address, port);//待发送的包裹
ds.send(dp);//发送
ds.close();//发送完毕,释放资源
}
}
复制代码
使用UDP协议开发接收端: 用DatagramSocket来监听发送端发送过来的数据:this
DatagramSocket ds = new DatagramSocket(7878);//接收端的监听端口
复制代码
用DatagramPacket做为接收数据的容器:spa
byte[] buf = new byte[1024];
int length = buf.length;
DatagramPacket dp = new DatagramPacket(buf, length);//直接做为接收数据的容器
复制代码
receive()接收数据,程序会在这里等待数据的到来:
ds.receive(dp);//等待数据到来
复制代码
与发送端同样,接收到数据以后一样须要释放对象ds的资源:
ds.close();//接收到数据,释放资源
复制代码
举个栗子🌰:
//UDP接收端
public class Demo3_UDP_Receive {
public static void main(String[] args) throws Exception {
DatagramSocket ds = new DatagramSocket(7878);//接收端的监听端口
byte[] buf = new byte[1024];
int length = buf.length;
DatagramPacket dp = new DatagramPacket(buf, length);//直接做为接收数据的容器
ds.receive(dp);//等待数据到来
String str = new String(dp.getData(), 0, dp.getLength());
System.out.println(str);//输出发送过来的数据
ds.close();//接收到数据,释放资源
}
}
复制代码
程序运行结果:
接收端的其余信息获取:
dp.getAddress();//获取发送端的IP地址
dp.getPort();//获取发送端的端口号
复制代码
使用UDP协议实现两个用户双向聊天:
一、新建一个SendThread发送线程类:
public class SendThread extends Thread {
private int port;
public SendThread(int port) {
this.port=port;
}
@Override
public void run() {
DatagramSocket ds=null;
try {
ds = new DatagramSocket();
Scanner inputstr = new Scanner(System.in);//输入数据
while (true) {
String str = inputstr.nextLine();
if (str.equals("end")) break;
byte[] buf = str.getBytes();//字节数组
int length = buf.length;//发送数据的长度
InetAddress address = InetAddress.getByName("127.0.0.1");//指定接收端的IP地址
//int port = 7878;//指定接收端的端口号
DatagramPacket dp = new DatagramPacket(buf, length, address, port);//发送包裹
ds.send(dp);//发送
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (ds!=null) {//有数据传输,因此须要释放资源
ds.close();
}
}
}
}
复制代码
二、再建一个ReceiveThread接收线程类:
public class ReceiveThread extends Thread {
private int port;
public ReceiveThread(int port) {
this.port=port;
}
@Override
public void run() {
DatagramSocket ds=null;
try {
ds = new DatagramSocket(port);//指定端口号来监听数据,与发送端发送数据包指定的端口相对应
while (true) {
byte[] buf = new byte[1024];
int length = buf.length;
DatagramPacket dp = new DatagramPacket(buf, length);//做为接收数据的容器
ds.receive(dp);//等待数据到来
String str = new String(dp.getData(), 0, dp.getLength());
System.out.println("收到来自端口"+dp.getPort()+"的消息:"+str);//输出发送过来的数据
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (ds!=null) {//有数据传输,因此须要释放资源
ds.close();
}
}
}
}
复制代码
三、新建Chant_User01类(用户1):
public class Chant_User01 {
public static void main(String[] args) {
new SendThread(7878).start();//用户1的发送线程,7878端口为用户2的接收线程监听端口
new ReceiveThread(7879).start();//用户1的接收线程,7879监听来自用户2发送的数据
}
}
复制代码
四、新建Chant_User02类(用户2):
public class Chant_User02 {
public static void main(String[] args) {
new ReceiveThread(7878).start();//用户2的接收线程,7878监听来自用户1发送的数据
new SendThread(7879).start();//用户2的发送线程,7879端口为用户1的接收线程监听端口
}
}
复制代码
实现效果:
用户1:
用户2:
TCP协议须要经过三次握手创建链接,客户端与服务端之间是一个双向通道,既能够发送数据(使用输出流),也能够接收数据(使用输入流)。因此使用TCP协议进行网络数据传输是可靠的,可是速度较慢!
使用TCP协议开发客户端: 客户端直接使用Socket,使用输出流OutputStream写入数据发送:
//TCP直接使用Socket
Socket s = new Socket("127.0.0.1", 8888);//与TCP接收端创建链接
//使用输出流来传输数据
OutputStream output = s.getOutputStream();
output.write("ww.baidu.com".getBytes());//向服务端写入数据
s.close();
复制代码
使用TCP协议开发服务端: 服务端使用ServerSocket,accept()等待接收客户端发送的TCP链接请求,与客户端建立链接成功以后会返回一个socket对象,socket对象能够建立输入流InputStream接收客户端发送的数据,也能够建立输出流OutputStream发送数据。
ServerSocket ss = new ServerSocket(8888);//指定服务端监听端口
Socket client = ss.accept();//等待链接,创建与客户端的链接
InputStream input = client.getInputStream();//使用输入流来接收数据
byte[] buf = new byte[1024];
int length = input.read(buf);//等待客户端发送数据
client.close();//关闭链接
ss.close();
复制代码
使用TCP协议实现两端双向聊天功能:
一、新建TCP_Client客户端类:
//TCP客户端
public class TCP_Client {
public static void main(String[] args) throws Exception {
Socket s = new Socket("127.0.0.1", 8888);//与Server端创建链接
OutputStream output = s.getOutputStream();//使用输出流来发送数据
InputStream input = s.getInputStream();//使用输入流接收来自Server的数据
/**
* 匿名内部类建立一个线程来接收数据
* */
new Thread() {
public void run() {
byte[] buf = new byte[1024];//字节数组容器
int length = -1;
try {
while ((length = input.read(buf))!=-1) {//等待服务端发送数据
System.out.println(new String(buf, 0, length));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
/**
* 发送数据
* */
Scanner scanner = new Scanner(System.in);
while (true) {
String in_str = scanner.nextLine();
if (in_str.equals("end"))break;
output.write(in_str.getBytes());//向Server端写入数据
}
s.close();//关闭链接
}
}
复制代码
一、新建TCP_Server服务端类:
//TCP链接的服务端
public class TCP_Server {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(8888);//指定服务端监听端口
Socket client = ss.accept();//等待链接,创建与客户端的链接
System.out.println("客户端已链接进来!");
InputStream input = client.getInputStream();//使用输入流来接收数据
OutputStream output = client.getOutputStream();//使用输出流发送数据
/**
* 匿名内部类建立一个线程来发送数据
* */
new Thread() {
public void run() {
Scanner scanner = new Scanner(System.in);
while (true) {
String str = scanner.nextLine();
if (str.equals("end"))break;
try {
output.write(str.getBytes());//向客户端写入数据
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
/**
* 接收数据
* */
byte[] buf = new byte[1024];
int length = -1;
while ((length = input.read(buf))!=-1) {//等待客户端发送数据
System.out.println(new String(buf, 0, length));
}
client.close();//关闭与客户端的链接
ss.close();//关闭监听
}
}
复制代码
运行结果:
客户端:
服务端:
多个客户端发送数据,一个服务端接收数据:
一、新建TCP_Server_Many类,能够接收多个客户端链接的TCP服务端和处理多个客户端的数据:
public class TCP_Server_Many {
public static void main(String[] args) {
new VerbClientConnect().start();//启动服务端监听线程监听多个客户端的链接
}
}
//监听多个客户端的链接
class VerbClientConnect extends Thread {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(8888);
int i=0;
while (true) {
Socket socket = serverSocket.accept();//等待请求链接
i++;
System.out.println("接收到一个客户端的链接:Client"+i+socket.getInetAddress());
new ClientMessage(socket,i).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//处理客户端发送的消息
class ClientMessage extends Thread {
private Socket socket;
private int i;
public ClientMessage(Socket socket, int i) {
this.socket=socket;
this.i=i;
}
@Override
public void run() {
try {
InputStream input = socket.getInputStream();//使用输入流来接收数据
byte[] buf = new byte[1024];
int length = -1;
while ((length = input.read(buf))!=-1) {//等待客户端发送数据
System.out.println("来自客户端Client"+i+"的消息:"+new String(buf, 0, length));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (socket!=null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
复制代码
二、新建TCP_Client_Many类,能够发送多条数据的TCP客户端:
public class TCP_Client_Many {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 8888);//请求链接
OutputStream output = socket.getOutputStream();//使用输出流来发送数据
Scanner scanner = new Scanner(System.in);
while (true) {
String str = scanner.nextLine();
if (str.equals("end"))break;
output.write(str.getBytes());//向服务端发送数据
}
socket.close();
}
}
复制代码
运行效果:
Client1:
Client2:
Client3:
服务端:
今日寄语:
欢迎关注我的微信公众号:桃李报春