JAVA Soket、ServerSocket通信

本文介绍如何使用 Java 的 Socket 和 ServerSocket 类实现简单的客户端与服务器通信,包括 IP 地址和端口号的基础配置,通过示例代码展示了简易聊天室的具体实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JAVA Soket、ServerSocket通信

IP地址和端口号

  • 打开命令提示符输入 :cmd,输入ipconfig后按下回车,找到ivp4地址。它就是你的IP地址。
  • 创建一个服务器非常简单,在构造方法里面输入一个端口号,这个端口号有一个范围0~65535:
    ServerSocket server=new ServerSocket(9090);
    如果你看到这样的异常信息:java.net.BindException: Address already in use: JVM_Bind那就说明这个端口被占用了,换一个就好了。
  • 有了IP地址和端口号我们就完成客户机和服务器通信的第一步了。

Soket和ServerSocket

Socket类代表一个客户端套接字,ServerSocket是服务器套接字。
为了从我的客户机发送一条信息到另一个客户机,我需要需要知道另一个客户机的IP地址和套接字端口。在Java里边,套接字指的是java.net.Socket类。
要实现一个服务器应用,我们的服务器必须随时待命,因为它不知道一个客户端应用什么时候会尝试去连接它。为了让应用能随时待命,需要使用java.net.ServerSocket类。这是服务器套接字的实现。

客户机与服务器通信

public class ChatServer { 
    public void setUpServer(int port){ 
        try{ 
            ServerSocket server=new  ServerSocket(port); 
            Socket client=server.accept(); //从连结对象上得到输入输出流对象  
            OutputStream out=client.getOutputStream();  
            InputStream ins=client.getInputStream();  
            String s="你好,欢迎来javaKe.com\r\n";    
            byte[] data=s.getBytes();//取得组成这个字符串的字节       
            out.write(data); //用输出对象发送数据!      
            out.flush();//强制输出      
            client.close();//半闭与客户机的连结 
        }catch(Exception ef){ 
            ef.printStackTrace(); 
        } 
    } 
    public static void main(String[] args) {        
        ChatServer cs=new ChatServer(); 
        cs.setUpServer(9090); 
    }
}

简易聊天室

ChatServer.java

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ChatServer {
    /**
     * 在指定端口上启动一个服务器
     * @param port:服务器所以的端口
     */
    public void setUpServer(int port) {
        ServerSocket server = null;
        try {
            server = new ServerSocket(port);
            System.out.println("服务器创建成功!" + port);
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            // 建立绑定在指定端口上的服务器对象
            while (true) { // 让服务器循环等待
                Socket client = server.accept();
                System.out.println("client connected!");
                // 从连结对象上得到输入输出流对象
                OutputStream out = client.getOutputStream();
                InputStream ins = client.getInputStream();
                String s = "Welcome to javaKe.com\r";
                byte[] data = s.getBytes();// 取得组成这个字符串的字节
                out.write(data); // 用输出对象发送数据
                out.flush();// 强制输出
                int in = 0; // 一个字节一个字节的读取客户机的输入
                StringBuffer str = new StringBuffer();
                while (!str.toString().trim().equals("exit")) {
                    str = new StringBuffer();
                    in = 0;
                    while (in != 13) {// 如果读到不是13,即回车字符
                        try {
                            in = ins.read();
                            str.append((char) in);
                            // System.out.println("读到的一个是: " + in);
                        } catch (Exception e) {
                        }
                    }
                    System.out.println(str.toString().trim());
                }
                System.out.println("客户机按了回车,退出:" + in);
                client.close();// 半闭与这个客户机的连结
            }
        } catch (Exception ef) {
            ef.printStackTrace();
        }
    }

    // 主函数
    public static void main(String[] args) {
        ChatServer cs = new ChatServer();
        cs.setUpServer(9091);

    }
}

Client.java

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;

public class Client {

    private Link link;

    public Client(){
        JFrame jf = new JFrame("客户端");
        jf.setSize(500, 200);
        jf.setDefaultCloseOperation(3);
        jf.setLocationRelativeTo(null);
        jf.setLayout(new FlowLayout());

        JButton jb1 = new JButton("连接服务器");
        JButton jb2 = new JButton("发送");

        final JTextField jt = new JTextField();
        jt.setPreferredSize(new Dimension(400, 30));

        jf.add(jb1);
        jf.add(jb2);
        jf.add(jt);

        jb1.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {
                //这是我电脑的IP地址,9091端口是我新建的端口
                link = new Link("172.20.10.2", 9091, jt);
                link.linkServer();
                link.start();
            }
        });

        jb2.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {
                link.sendMsg();
            }
        });

        jf.setVisible(true);
    }

    public static void main(String[] args) {
        Client cl = new Client();
    }

}

Link.java

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import javax.swing.JTextField;

public class Link extends Thread {
    private String ip;
    private int port;
    private JTextField msgjt;
    private InputStream ins;
    private OutputStream ous;

    public Link(String ip, int port, JTextField msgjt) {
        this.ip = ip;
        this.port = port;
        this.msgjt = msgjt;
    }

    public void linkServer() {
        try {
            Socket socket = new Socket(ip, port);
            ins = socket.getInputStream();
            ous = socket.getOutputStream();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void sendMsg() {
        String msg = msgjt.getText() + "\r\n";
        msgjt.setText("");
        try {
            ous.write(msg.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void run() {
        while (true) {
            try {
                StringBuffer str = new StringBuffer();
                int i = ins.read();
                while (i != 13) {
                    str.append((char) i);
                    i = ins.read();
                }
                System.out.println("服务器:" + str);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值