Socket

Socket

  • 据交换,这个双向连接的一端称为一个Socket
  • java.net包中定义的两个类Socket和ServerSocket,分别用来实现双向连接的client和server端
  • 建立连接时所需的寻址信息为远程计算机的ip地址和端口号(Port number)
//Server端
import java.net.*;
import java.io.*;
public class TcpServer {
    public static void main(String[] args) throws Exception{
        ServerSocket ss = new ServerSocket(6666);
        while(true) {
            Socket s = ss.accept();
            DataInputStream dis = new DataInputStream(s.getInputStream());
            System.out.println(dis.readUTF());
            dis.close();
            s.close();
        }
    }
}
//Client端
import java.io.*;
import java.net.*;
public class TcpClient {
    public static void main(String[] args) throws Exception{
        Socket s = new Socket("127.0.0.1",6666);
        OutputStream os = s.getOutputStream();
        DataOutputStream dos = new DataOutputStream(os);
        dos.writeUTF("Hello Server");
        dos.flush();
        dos.close();
    }
}

 首先说Server端,Server端用的类是ServerSocket,构造方法中的参数表示监听哪个端口,一个服务器或者一台电脑上有很多端口,其中有一些是已经被占用的,就不能用,这里我随便用6666这个端口  然后是Client端,Client端用的类是Socket,构造方法中的两个参数,第一个是访问的ip,127.0.0.1代表的ip表示本机,也可以用localhost替换,第二个参数代表访问Server端的哪个端口  随后Client端通过流,向Server端发送消息,Server端调用accept方法首先允许Client端访问,然后也通过流读入Client发送的消息,整个过程是个死循环,模拟真实服务器24小时不间断的操作

//Server端
import java.net.*;
import java.io.*;
public class TestServer {
    public static void main(String[] args) {
        try {
            ServerSocket s = new ServerSocket(6666);
            while(true) {
                Socket s1 = s.accept();
                OutputStream os = s1.getOutputStream();
                DataOutputStream dos = 
                        new DataOutputStream(os);
                dos.writeUTF("Hello," + s1.getInetAddress() + ",Port#" + s1.getPort());
                dos.close();
                s1.close();
            }
        }catch (IOException e) {
            e.printStackTrace();
            System.out.println("程序运行错误:" + e);
        }
    }
}
//Client端
import java.io.*;
import java.net.*;
public class TestClient {
    public static void main(String[] args) {
        try {
            Socket s = new Socket("localhost",6666);
            InputStream is = s.getInputStream();
            DataInputStream dis = 
                    new DataInputStream(is);
            System.out.println(dis.readUTF());
            dis.close();
            s.close();
        }catch(IOException e) {
            e.printStackTrace();
            System.out.println("服务器连接超时" + e);
        }
    }
}

 上面的程序不再是Client向Server端发送消息,而是Server端向Client端发送消息,在Server端中输出代码里,有一个方法getInetAddress,这个返回的不是Serveer端的ip,返回的是Client端的IP  其次,getPort方法返回的是Client出来的端口号,Client使用哪个端口是系统随机分配的,而Server端开发什么端口是自定义的,这两个有区别

//Server端
import java.net.*;
import java.io.*;
public class TestSocketServer {
    public static void main(String[] args) {
        InputStream in = null;
        OutputStream out = null;
        try {
            ServerSocket s = new ServerSocket(6666);
            Socket s1 = s.accept();
            in = s1.getInputStream();
            out = s1.getOutputStream();
            DataOutputStream dos = new DataOutputStream(out);
            DataInputStream dis = new DataInputStream(in);
            String ss = null;
            if((ss = dis.readUTF()) != null) {
                System.out.println(s);
                System.out.println("from:" + s1.getInetAddress());
                System.out.println("Port:" + s1.getPort());
            }
            dos.writeUTF("Hello");
            dis.close();
            dos.close();
            s1.close();
        }catch(IOException e) {
            e.printStackTrace();
        }
    }
}
//Client端
import java.net.*;
import java.io.*;
public class TestSocketClient {
    public static void main(String[] args) {
        InputStream is = null;
        OutputStream os = null;
        try {
            Socket s = new Socket("localhost",6666);
            is = s.getInputStream();
            os = s.getOutputStream();
            DataInputStream dis = new DataInputStream(is);
            DataOutputStream dos = new DataOutputStream(os);
            dos.writeUTF("hey");
            String ss = null;
            if((ss = dis.readUTF()) != null) {
                System.out.println(ss);
            }
            dis.close();
            dos.close();
            s.close();
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

 上面的程序实现了Server和Client相互传输信息

聊天小程序

import java.net.*;
import java.io.*;
public class TalkServer {
    public static void main(String[] args) {
        try {
            ServerSocket server = new ServerSocket(6666);
            Socket socket = server.accept();
            String line = null;
            BufferedReader br = 
                    new BufferedReader(
                            new InputStreamReader(socket.getInputStream()));
            PrintWriter pw = 
                    new PrintWriter(socket.getOutputStream());
            BufferedReader br1 = 
                    new BufferedReader(
                            new InputStreamReader(System.in));
            System.out.println("Client:" + br.readLine());
            line = br1.readLine();
            while(!line.equals("exit")) {
                pw.println(line);
                pw.flush();
                System.out.println("Server:" + line);
                System.out.println("Client:" + br.readLine());
                line = br1.readLine();
            }
            br.close();
            br1.close();
            pw.close();
            server.close();
            socket.close();
        }catch(Exception e) {
            e.printStackTrace();
        }
        
    }
}
import java.net.*;
import java.io.*;
public class TalkClient {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("localhost",6666);
            BufferedReader br = 
                    new BufferedReader(
                            new InputStreamReader(System.in));
            PrintWriter pw = 
                    new PrintWriter(socket.getOutputStream());
            BufferedReader br1 = 
                    new BufferedReader(
                            new InputStreamReader(socket.getInputStream()));
            String readLine;
            readLine = br.readLine();
            while(!readLine.equals("exit")){
                pw.println(readLine);
                pw.flush();
                System.out.println("Client:" + readLine);
                System.out.println("Server:" + br1.readLine());
                readLine = br.readLine();
            }
            br.close();
            br1.close();
            pw.close();
            socket.close();
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
}

补充

 accept和readUTF方法是阻塞式的,也就是说如果没有Client向Server端发送消息或者访问端口,Server就会一直等待,不会执行下面的语句

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Hongten

java开发_STMP邮箱客户端_发送邮件

http://zhiwenweb.cn/jszx/czxt/201009/20179.html

1213
来自专栏马洪彪

Java服务器端生成报告文档:使用SQL Server Report Service(SSRS)

SQL Server Report Service(SSRS)提供了Asp.Net和WinForm两类客户端组件封装,因此使用C#实现SSRS报表的导出功能,仅...

3475
来自专栏用户2442861的专栏

java IO流之三 使用缓冲流来读写文件

http://blog.csdn.net/a107494639/article/details/7586689

973
来自专栏Java学习之路

JavaTCP和UDP套接字编程

原文地址:http://www.cnblogs.com/MindMrWang/p/8919890.html 在我们刚开始入门Java后端的时候可能你会觉得有点...

3305
来自专栏FreeBuf

scapy在wlan中的应用

Scapy 又是scapy,这是python的一个网络编程方面的库,它在wlan中也有很强大的应用。一般我们买块网卡,然后aircrack-ng套件爆破一下邻居...

29410
来自专栏拂晓风起

java web 自定义错误页面 完整jsp错误页面代码(同时写错误日志) error.jsp

1155
来自专栏黑泽君的专栏

Java网络编程多线程改进上传文件

Java网络编程多线程改进上传文件   服务器的代码用线程进行封装(多线程),这样可以模拟一个同时接收多人上传文件的服务器。   (用循环也可以...

962
来自专栏青玉伏案

设计模式(七): 通过转接头来观察"适配器模式"(Adapter Pattern)

在前面一篇博客中介绍了“命令模式”(Command Pattern),今天博客的主题是“适配器模式”(Adapter Pattern)。适配器模式用处还是比较多...

1918
来自专栏XAI

微信二次开发Java自定义菜单事件实现

微信二次开发--java http://blog.csdn.net/lyq8479/ 这个是柳峰的CSDN博客。大家可以看大神的教程。里面有所有的代码。 项目整...

6786
来自专栏青青天空树

趣味题:恺撒Caesar密码(c++实现)

描述:Julius Caesar 生活在充满危险和阴谋的年代。为了生存,他首次发明了密码,用于军队的消息传递。假设你是Caesar 军团中的一名军官,需要把Ca...

682

扫码关注云+社区