java网络聊天程序_java实现一个简单的网络聊天程序

代码

服务器端

package socket_demo;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

public class server {

public static void main(String[] args) throws Exception {

// 监听指定的端口,阻塞直至客户端连接此端口

int port = 23333;

ServerSocket server = new ServerSocket(port);

System.out.println("server is waiting...");

Socket socket = server.accept();

System.out.println("Connected!");

// 读取从客户端返回的输入流,至尾端时返回-1

InputStream input = socket.getInputStream();

byte[] bytes = new byte[1024];

int len;

StringBuilder get = new StringBuilder();

while ((len = input.read(bytes)) != -1) {

get.append(new String(bytes, 0, len, "UTF-8"));

}

System.out.println("get message from client: " + get);

OutputStream output = socket.getOutputStream();

String sent = "Hi there";

output.write(sent.getBytes("UTF-8"));

System.out.println("sent message to client: " + sent);

// 关闭socket与服务器端

input.close();

output.close();

socket.close();

server.close();

}

}

客户端

package socket_demo;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

public class client {

public static void main(String args[]) throws Exception {

// 连接本地主机,端口自设,与服务端一致即可

String host = "127.0.0.1";

int port = 23333;

// 通过socket与服务端建立连接

Socket socket = new Socket(host, port);

if(socket.isConnected()){

System.out.println("Connected!");

}

// 将要发送的信息写入输出流

OutputStream output = socket.getOutputStream();

String sent = "hello";

socket.getOutputStream().write(sent.getBytes("UTF-8"));

// 关闭客户端的输出流(单向,并未关闭socket)

socket.shutdownOutput();

System.out.println("sent message to server: " + sent);

// 读取从server返回的输入流

InputStream input = socket.getInputStream();

byte[] bytes = new byte[1024];

int len;

StringBuilder get = new StringBuilder();

while ((len = input.read(bytes)) != -1) {

get.append(new String(bytes, 0, len,"UTF-8"));

}

System.out.println("get message from server: " + get);

// 关闭socket

input.close();

output.close();

socket.close();

}

}

测试结果

服务器端

d4f768efbcd2a0399a1cccb89535b98e.png

客户端

c7804592dabbfaa656bd9213f1f6a26e.png

JAVA Socket API分析

以上代码用到的JAVA SOCKET API主要有:

Socket(InetAddress address, int port) --创建一个流套接字并将其连接到指定的IP地址与指定端口

ServerSocket(int port)--服务器端绑定一个窗口

server.accept()--服务器端等待连接(持续阻塞)

socket.getInputStream()--返回此套接字的输入流

socket.getOutputStream()--返回此套接字的输出流

socket.close()--关闭此套接字

JAVA中方法的实现都要通过JVM翻译给系统执行,所以JAVA SOCKET API与系统(本例为windows)SOCKET API有着对应关系。

我们通过在IDEA中使用Ctrl+Alt+H与Ctrl+Alt+B跟踪查看api的调用栈,以server.accept()为例

1d4f1c0644816fecd363f96e7adc8fbb.png

双击右边函数名,查看其调用,进一步查看ServerSocket.implAccept(Socket)

aea68b4093668cb2766680404f5227e0.png

1de183b817db78838e0d1318ab421803.png

34b6007593c5d2089755e5b9127890d5.png

a9d29fd0b45b8c1d86a9d91aec7cf0b7.png

067a3111fb1e36b6f2b05744e4dd5e60.png

c0cfe0f30cc729164223a8e013871470.png

这里accept0()是一个native api,无法再继续上溯

完整的调用栈为server.accept()->ServerSocket.implAccept(Socket) (java.net)->SocketImpl.accept(SocketImpl)

->AbstractPlainSocketImpl.socketAccept(SocketImpl)->PlainSocketImpl.accept0(int, InetSocketAddress[])

综上,java socket中的server.accept()对应windows socket中的accept0(int var0, InetSocketAddress[] var1)

其它socket api也都有着类似的对应关系,通过查看调用栈可以一一查找,这里不再赘述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值