网络编程
把分布在不同地理区域的计算机专门的外部设备用通信线路互联成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息、共享硬件、软件、数据信息等资源
【4】TCP协议:可靠的
建立链接:三次握手
释放链接:四次挥手
InetAddress 和 InetScoketAddress
【1】InetAddress 封装了IP
【2】InetScoketAddress 封装了IP ,端口号
InetAddress
public static void main(String[] args) throws UnknownHostException {
InetAddress ia = InetAddress.getByName("192.169.199.222");
System.out.println(ia);
InetAddress localhost = InetAddress.getByName("localhost");
System.out.println(localhost);
InetAddress ia2 = InetAddress.getByName("LAPTOP-0FIKEUU1");
System.out.println(ia2);
InetAddress ia3 = InetAddress.getByName("www.baidu.com");
System.out.println(ia3);
System.out.println(ia3.getHostName());
System.out.println(ia3.getHostAddress());
}
InetSocketAddress
public static void main(String[] args) {
InetSocketAddress isa = new InetSocketAddress("192.169.199.222",8080);
System.out.println(isa.getHostName());
System.out.println(isa.getPort());
InetAddress ia = isa.getAddress();
}
网络通信的原理
套接字 - Socke
TCP 通信功能
功能:模拟网站的登录,客户端输入账号密码,服务器端进行验证
双向通信
功能:客户端发送一句话到服务器,服务器端相应一句话给客户端
客户端
public class TestClient {
public static void main(String[] args) throws IOException {
Socket s = new Socket("172.26.160.1",8888);
OutputStream os = s.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF("你好");
InputStream is = s.getInputStream();
DataInputStream dis = new DataInputStream(is);
System.out.println("服务器端对我说:"+dis.readUTF());
dos.close();
os.close();
s.close();
}
}
服务器
public class TestServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
DataInputStream dis = new DataInputStream(is);
System.out.println("客户端发来的数据为:"+dis.readUTF());
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF("你好,我是服务器端,我收到了你的信息");
dis.close();
is.close();
socket.close();
serverSocket.close();
}
}
测试:
先开启服务器,在开启客户端
登录功能
客户端发送账号密码,服务器端判断进行账号密码是否正确,返回给客户端信息,并加入异常处理机制
在User实体类中,要注意序列化问题!!
客户端
public class TestServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
ObjectInputStream ois = null;
OutputStream os = null;
DataOutputStream dos = null;
try{
serverSocket= new ServerSocket(8888);
socket = serverSocket.accept();
is = socket.getInputStream();
ois= new ObjectInputStream(is);
boolean flag = false;
User user = (User) ois.readObject();
if (user.getUsername().equals("admin") && user.getPassword().equals("123456")){
flag = true;
}
os = socket.getOutputStream();
dos = new DataOutputStream(os);
dos.writeBoolean(flag);
}catch (Exception e){
e.printStackTrace();
}finally {
if (dos != null) {
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
服务器
public class TestServer {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
boolean flag = false;
User user = (User) ois.readObject();
if (user.getUsername().equals("admin") && user.getPassword().equals("123456")){
flag = true;
}
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeBoolean(flag);
ois.close();
is.close();
socket.close();
serverSocket.close();
}
}
多线程接收用户请求
解决:服务器必须一直在监听,等待客户端的请求,客户端不需要更改代码。
服务器
public static void main(String[] args) {
System.out.println("服务器启动成功....");
ServerSocket serverSocket = null;
Socket socket = null;
int count = 0;
try {
serverSocket = new ServerSocket(8888);
while (true) {
socket = serverSocket.accept();
new ServerThread(socket).start();
count ++;
System.out.println("当前是第:"+count+"个用户访问服务器,对应的用户是:"+ socket.getInetAddress().toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
多线程
public class ServerThread extends Thread{
Socket socket = null;
InputStream is = null;
ObjectInputStream ois = null;
OutputStream os = null;
DataOutputStream dos = null;
public ServerThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
is = socket.getInputStream();
ois= new ObjectInputStream(is);
boolean flag = false;
User user = (User) ois.readObject();
if (user.getUsername().equals("admin") && user.getPassword().equals("123456")){
flag = true;
}
os = socket.getOutputStream();
dos = new DataOutputStream(os);
dos.writeBoolean(flag);
}catch (Exception e){
e.printStackTrace();
}finally {
if (dos != null) {
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
UDP通信
TCP
客户端:Socket 使用流:输出流
服务器端:ServerSocket 使用流:输入流
UDP:
发送方:DatagramSocket 发送:数据包 DatagramPacket
接收方:DatagramSocket 发送:数据包 DatagramPacket
UDP单项通信
发送方:学生
接收方:老师
功能:学生对老师说一句话
发送方
public class TestSend {
public static void main(String[] args) throws IOException {
System.out.println("学生上线...");
DatagramSocket ds = new DatagramSocket(8888);
String str = "你好,老师";
byte[] bytes = str.getBytes();
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("localhost"), 9999);
ds.send(dp);
ds.close();
}
}
接收方
public class TestReceive {
public static void main(String[] args) throws IOException {
System.out.println("老师上线了....");
DatagramSocket ds = new DatagramSocket(9999);
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes,bytes.length);
ds.receive(dp);
byte[] data = dp.getData();
String s = new String(data,0,dp.getLength());
System.out.println(s);
ds.close();
}
}
UDP双向通信
解决问题:双向通信,异常处理,持续对话,下线提示
学生:发送方
public class TestSend {
public static void main(String[] args) {
System.out.println("学生上线...");
DatagramSocket ds = null;
try {
ds= new DatagramSocket(8888);
while (true){
Scanner sc = new Scanner(System.in);
System.out.println("学生(bye,结束标识):");
String str = sc.next();
byte[] bytes = str.getBytes();
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("localhost"), 9999);
ds.send(dp);
if (str.equals("bye")){
break;
}
byte[] b = new byte[2048];
DatagramPacket dp2 = new DatagramPacket(b,b.length);
ds.receive(dp2);
byte[] data = dp2.getData();
String s = new String(data,0,dp2.getLength());
System.out.println("老师说:"+s);
}
}catch (SocketException e){
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
ds.close();
}
}
}
接收方:老师
public class TestReceive {
public static void main(String[] args){
System.out.println("老师上线了....");
DatagramSocket ds = null;
try{
ds= new DatagramSocket(9999);
while (true){
byte[] bytes = new byte[2048];
DatagramPacket dp = new DatagramPacket(bytes,bytes.length);
ds.receive(dp);
byte[] data = dp.getData();
String s = new String(data,0,dp.getLength());
System.out.println("学生说:"+s);
if (s.equals("bye")){
System.out.println("学生下线了,老师也下线了");
break;
}
Scanner sc = new Scanner(System.in);
System.out.println("老师:");
String str = sc.next();
byte[] bytes1 = str.getBytes();
DatagramPacket dp2 = new DatagramPacket(bytes1, bytes1.length, InetAddress.getByName("localhost"), 8888);
ds.send(dp2);
}
}catch (SocketException e){
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
ds.close();
}
}
}
|