美文网首页
网络编程--使用TCP/IP的套接字(Socket)进行通信

网络编程--使用TCP/IP的套接字(Socket)进行通信

作者: 鉴闻俗说 | 来源:发表于2018-01-24 10:36 被阅读0次

1、什么是Socket?

Socket是连接运行在网络上的两个程序间的双向通讯的端点。

2、使用Socket进行网络通信的过程

(1)服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和和监听客户的连接请求。
(2)客户程序根据服务器程序所在的主机名和端口号发出连接请求。


image.png

(3)如果一切正常,服务器接受连接请求。并获得一个新的绑定到不同端口地址的套接字。
(4)客户和服务器通过读写套接字进行通讯。


image.png
(5)使用ServerSocket和Socket实现服务器端和客户端的Socket通信总结:
  • 建立Socket连接
  • 获得输入/输出流
  • 读/写数据
  • 关闭输入/输出流
  • 关闭Socket
image.png

3、代码实现

(1)未使用线程的实现
  • 服务器端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 使用ServerSocket和Socket实现服务器端和客户端的 Socket通信
 * 这是服务器端
 * @author Chuan
 *
 */
public class TcpServer
{
    public static void main(String[] args) throws IOException
    {
        ServerSocket serverSocket = new ServerSocket(5000);
        
        Socket socket = serverSocket.accept();
        
        InputStream is = socket.getInputStream();
        OutputStream os = socket.getOutputStream();
        
        //读取客户端的会话
        byte[] buffer = new byte[1024];
        int length = is.read(buffer);
        System.out.println(new String(buffer, 0, length));
        
        os.write("welcom".getBytes());
        
        
        is.close();
        os.close();
        socket.close();
        serverSocket.close();
    }
}
  • 客户端代码
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 使用ServerSocket和Socket实现服务器端和客户端的 Socket通信
 * 这是客户端
 * @author Chuan
 *
 */
public class TcpClient
{
    public static void main(String[] args) throws UnknownHostException, IOException
    {
        Socket socket = new Socket("127.0.0.1", 5000);
        
        OutputStream oStream = socket.getOutputStream();
        InputStream iStream = socket.getInputStream();
        
        //向服务端发送消息
        oStream.write("hello".getBytes());
        
        //读取服务端发送过来的消息
        byte[] buffer = new byte[1024];
        int length = iStream.read(buffer);
        System.out.println(new String(buffer, 0, length));
        
        oStream.close();
        iStream.close();
        socket.close();
    }
}
(2)使用线程实现
  • 服务器端MainServer
    服务器端使用了两个线程:接收会话线程ServerInputThread,发送会话线程ServerOutputThread。需要注意的是在服务端使用了一个whlie循环,而客户端没有。这样做的原因是服务端可能需要处理来自不同客户端的连接将请求,没有一个客户端请求连接就会获得一个新的绑定到不同端口地址的套接字
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *服务器端
 * @author Chuan
 *
 */
public class MainServer
{
    public static void main(String[] args) throws IOException
    {
        @SuppressWarnings("resource")
        ServerSocket ss = new ServerSocket(4000);
        
        /**
         * 此处的while循环是为了可能有多个客户端,但是本程序中当有多个客户端时,
         * 客户端向服务端发消息没问题,服务端再往客户端发消息就会出问题,不能发送给相应的客户端
         */
        while (true)
        {
            Socket socket = ss.accept();
            new ServerInputThread(socket).start();
            new ServerOutputThread(socket).start();
        }   
    }
}
  • 接收会话线程ServerInputThread
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

/*
 * 服务器端的读取会话线程
 */
public class ServerInputThread extends Thread
{
    private Socket socket;
    
    public ServerInputThread(Socket socket)
    {
        this.socket = socket;
    }

    @Override
    public void run()
    {
        try
        {
            InputStream is = socket.getInputStream();
            byte[] buffer = new byte[1024];
            int length;
            while (true)
            {   
                length = is.read(buffer);
                System.out.println(new String(buffer, 0, length));
                
            }
            
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
  • 发送会话线程ServerOutputThread
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

/*
 * 服务器端的发送会话线程
 */
public class ServerOutputThread extends Thread
{
    private Socket socket;
    
    public ServerOutputThread(Socket socket)
    {
        this.socket = socket;
    }
    
    @Override
    public void run()
    {
        try
        {
            OutputStream os = socket.getOutputStream();
            while (true)
            {
                BufferedReader br = new BufferedReader(
                        new InputStreamReader(System.in));
                String str = br.readLine();
                os.write(str.getBytes());
            }
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
    }
}
  • 客户端代码MainClient
    客户端代码中也使用了两个线程:接收会话线程ClientInputThread,发送会话线程ClientOutputThread
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 客户端
 * @author Chuan
 *
 */
public class MainClient
{
    public static void main(String[] args) throws UnknownHostException, IOException
    {
        Socket socket = new Socket("127.0.0.1", 4000);
        
            new ClientInputThread(socket).start();
            new ClientOutputThread(socket).start();
    }
}
  • 接收会话线程ClientInputThread,和服务端接手会话线程大同小异
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

/**
 * 客户端的读取会话线程
 */
public class ClientInputThread extends Thread
{
    private Socket socket;
    
    public ClientInputThread(Socket socket)
    {
        this.socket = socket;
    }
    
    @Override
    public void run()
    {
        try
        {
            InputStream is = socket.getInputStream();
            byte[] buffer = new byte[1024];
            int length;
            while (true)
            {   
                length = is.read(buffer);
                System.out.println(new String(buffer, 0, length));
                
            }
            
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
  • 发送会话线程ClientOutputThread
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

/**
 * 客户端的发送会话线程
 */
public class ClientOutputThread extends Thread
{
    private Socket socket;
    
    public ClientOutputThread(Socket socket)
    {
        this.socket = socket;
    }
    
    @Override
    public void run()
    {
        try
        {
            OutputStream os = socket.getOutputStream();
            while (true)
            {
                BufferedReader br = new BufferedReader(
                        new InputStreamReader(System.in));
                String str = br.readLine();
                os.write(str.getBytes());
            }
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
    }
}

相关文章

  • CocoaAsyncSocket --Socket学习

    Socket理论 套接字(Socket)概念 套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信...

  • iOS网络编程之Socket

    1、套接字(socket)概念 套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元...

  • python核心编程第三版

    第二章-网络编程 socket() 嵌套字创建tcp/ip套接字tcpsock - socket.socket(s...

  • HTTP详解,七层协议

    socket(套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信必须的五种信息...

  • 基于socket的“抽奖”

    socket(套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信必须的五种信息...

  • iOS socket相关知识

    socket(套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信必须的五种信息...

  • IOS socket

    socket(套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信必须的五种信息...

  • Socket基础知识

    socket(套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信必须的五种信息...

  • Day18总结

    一.网络通信过程TCP协议和UDP协议二.socket编程 1.socket编程定义:socket又叫套接字。指的...

  • socket知识点补充

    socket套接字 通信基石 包含本地.远端ip地址,本地.远端通信协议,连接协议支持tcp/ip网络通信多个通信...

网友评论

      本文标题:网络编程--使用TCP/IP的套接字(Socket)进行通信

      本文链接:https://www.haomeiwen.com/subject/dteeaxtx.html