java.net.socket api_编写 Java 聊天程序并探究Socket API

先上一张网络聊天程序运行图:

669db465e504eac5af6ad5ebfcc2b520.png

31fedd7bc41cd65d936ae1113986f465.png

功能实现的很简单,客户端输入服务器IP和端口信息连接服务器,建立连接之后,客户端和服务器就可以进行双向通信了。

源码如下:

client端 源代码

import java.io.*;importjava.net.Socket;importjava.util.Scanner;public class Client extends Netutil implementsRunnable{

String IPAdress;intport;

Client(String IPAdress,intport){this.IPAdress=IPAdress;this.port=port;

}public static voidmain(String[] args) {

Scanner scanner= newScanner(System.in);

System.out.print("请输入IP地址:");

String ip=scanner.nextLine();

System.out.print("请输入端口号:");int port=scanner.nextInt();

Client client1=newClient(ip,port);

Thread thread1=newThread(client1);

thread1.start();

}

@Overridepublic voidrun() {try{

Socket s= new Socket(this.IPAdress, this.port);super.Oprate(s);

}catch(IOException e) {

e.printStackTrace();

}

}

}

Server端源代码:

import java.io.*;importjava.net.InetAddress;importjava.net.ServerSocket;importjava.net.Socket;importjava.util.Scanner;public class Server extendsNetutil {public static voidmain(String[] args) {newServer().Get();

}/*进入的方法*/

public voidGet() {try{

ServerSocket serverSocket= new ServerSocket(4432);

InetAddress inetAddress=InetAddress.getLocalHost();//System.out.println("开启服务器");

System.out.println("地址:" + inetAddress.getHostAddress() + "端口:" + 4432);

Socket accept;while (true) {

accept=serverSocket.accept();//System.out.println("主机"+accept.getRemoteSocketAddress()+"连接服务器");

Thread hander= new Thread(newHandler(accept));

hander.start();

}

}catch(IOException e) {

e.printStackTrace();

}

}/*** 内部处理类*/

class Handler extends Netutil implementsRunnable {

Socket socket;publicHandler(Socket socket) {this.socket =socket;

}

@Overridepublic voidrun() {try{super.Oprate(socket);

}catch(IOException e) {

e.printStackTrace();

}

}

}

}

聊天功能实现类:

importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.IOException;importjava.net.Socket;importjava.util.Scanner;public classNetutil {public void Oprate(Socket s) throwsIOException {

DataInputStream dataInputStream= newDataInputStream(s.getInputStream());

DataOutputStream dataOutputStream= newDataOutputStream(s.getOutputStream());newThread() {

@Overridepublic voidrun() {

String line;

String content= "";while (true) {try{

Thread.sleep(100);

content= "";while (!((line = dataInputStream.readUTF()).equals("EOF"))) {

content= content +line;//System.out.println(line);

}

}catch(Exception e) {

e.printStackTrace();

}

System.out.println("收到:" +content);

}

}

}.start();

Scanner scanner= newScanner(System.in);

String message;while (true) {

message=scanner.nextLine();if (message.equals("#qiut")) break;

dataOutputStream.writeUTF(message);

dataOutputStream.writeUTF("EOF");

dataOutputStream.flush();

}

dataInputStream.close();

dataOutputStream.close();

s.close();

}

}

聊天程序的流程图如下:

d0a781a9ef3b6c18ee5b86c862a4d9dd.png

但是,光会用JAVA编写聊天程序显然是不行的,让我们深入其API探讨一下socket的建立过程。

在程序中,客户端初始化了一个socket连接,用来连接服务器,

7cae3cb3ae4620d6ac433d1835757615.png

调试进入之后,调用的是如下构造方法

cf682bf293406c800019f55ea6585681.png

上图中的构造方法在参数处理之后,调用了自身的其他构造,其中,下图的构造方法中,address为服务器端口地址,localAddr为自身端口地址,stream为是否要打开传输流。

3ea9a8e43777154ed047413fe700a7a7.png

在构造函数中,首先调用的是setImpl( )方法,调试跟踪发现,impl采用的是

Impl=new SocksSocketimpl()构造的,impl是SocketImpl类型,实现了SocketOptions接口,用来描述socket的参数。

6d851b32f1c29c812bf1c31e9a1f642d.png

再往下,看看SocksSocketImpl是如何构造的。

71a1b6a6ed98adc1af3e7b700191974c.png

SocksSocketImpl构造函数为空方法,但是他继承了PlainSocketImpl类,在看看PlainSocketimpl类的构造方法,其中构造了DualStackPlainSocketImpl对象,DualStackPlainSocketImpl对象表示双向栈的Socket对象,为带有双向流socket.

f627d7fef18ecc4129cff869f1a3b930.png

DualStackPlainSocketImpl构造函数如下:

ebdd6fab1e3f52685b8cb3c04109b121.png

在看完了setImpl()函数调用的,过程之后,继续往下走,在Socket函数中,接下来调用了createImpl()方法,方法里面调用了create()方法。

09774947426c2bd6e06bb4aff9f4a157.png

在那之后,在try catch块中调用了DualStackPlainSocketImpl对象的bind和Conect方法,DualStackPlainSocketImpl对象中的的bind和Conect方法,调用的是本地的方法库,调用的是C中的bind和connect方法,C语言中的bind方法和connect方法在Java API中就不在深究了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值