C#中TCP协议网络通信技术

开发工具与关键技术:MyEclipse 10、TCP

作者:邓崇富

撰写时间:2019 年 5 月 7 日

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

TCP网络程序设计是利用Socket类编写通信程序。利用TCP协议进行通信的两个应用程序是有主次之分的,一个称为服务器程序,另一个称为客户机程序。

InetAddress

Java.net包中的InetAddress类是与IP地址相关的类,利用该类可以获取IP地址、主机地址等信息。

InetAddress类的常用方法如下表:

方       法

  返  回  值

      说   明

getByName(String host)

InetAddress

获取与Host相对应的InetAddress对象

getHostAddress()

String

获取InetAddress对象所包含的IP地址

getHostName()

String

获取IP地址的主机名

getLocalHost

InetAddress

返回本地主机的InetAddress对象

使用InetAddress类的getHostName()getHostAddress()方法获得本地主机名、本机IP地址。

代码如下:

public class Address {

   public static void main(String[] args) {

      InetAddress ip;//创建InetAddress对象

      try {

         ip = InetAddress.getLocalHost();//实例化对象

         String localname = ip.getHostName();//获取本机名

         String localip = ip.getHostAddress();//获取本机IP地址

         System.out.println("本机名:" + localname);

         System.out.println("本机IP地址:" + localip);

      } catch (UnknownHostException e) {

         // TODO Auto-generated catch block

         e.printStackTrace();

      }

   }

}

运行结果:

ServerSocket

Java.net包中的ServerSocket类用于表示服务器套接字,其主要功能是等待来自网络上的“请求”,它可通过指定的端口来等待连接的套接字。服务器套接字一次可以与一个套接字连接。如果多台客户机同时提出连接请求,服务器套接字会将请求连接的客户机存入列队中,然后从中取出一个套接字与服务器新建的套接字连接起来。若请求数大于最大容纳数,则多出的连接请求被拒绝。队列的默认大小是50

ServerSocket类的构造方法都抛出IOException异常,分别有以下几种形式:

  1. ServerSocket():创建非绑定服务器套接字。
  2. ServerSocket(int port):创建绑定到特定端口的服务器套接字。
  3. ServerSocket(int port,int backlog):利用指定的backlog创建服务器套接字并将其绑定到指定的本地端口号。
  4. ServerSocket(int port,int backlog,InetAddress bindAddress):使用指定的端口、侦听backlog和要绑定到的本地IP地址创建服务器。这种情况适用于计算机上有多块网卡和多个IP地址的情况,用于可以明确规定ServerSocket在哪块网卡或IP地址上等待客户的连接请求。

ServerSocket类的常用方法如下:

           

               

       

Accept()

Socket

等待客户机的连接。若连接,则创建一套接字

isBound()

boolean

判断ServerSocket的绑定状态

getInetAddress()

InetAddress

返回此服务器套接字的本地地址

isClosed()

boolean

返回服务器套接字的关闭状态

Close()

void

关闭服务器套接字

Bind(SocketAddress endpoint)

void

ServerSocket绑定到特定地址(IP地址和端口号)

getInetAddress()

int

返回服务器套接字等待的端口号

调用ServerSocket类的accept()方法会返回一个和客户端Socket对象相连接的Socket对象,服务器端的Socket对象使用getOutputStream()方法获得的输出流将指向客户端Socket对象使用getInputStream()方法获得的那个输入流;同样服务器端的Socket对象使用getInputStream()方法获得的输入流将指向客户端Socket对象使用getOutputStream()方法获得的那个输出流。也就是说,当服务器向输出流写入信息时,客户端通过相应的输入流就能读取,反之亦然。

TCP网络程序

在网络编程中如果只要求客户端向服务器发送消息,不要求服务器向客户端发送消息,称为单向通信。客户端套接字和服务器套接字连接成功后,客户端通过输出流发送数据,服务器则通过输入流接收数据。

以下是简单的单向的通信的例子(服务端代码):

public class MyTcp {

   private BufferedReader reader;// 创建BufferedReader对象

   private ServerSocket server;// 创建ServerSocket对象

   private Socket socket;// 创建Socket对象socket

   void getsever() {

      try {

         server = new ServerSocket(8998);// 实例化Socket对象

         System.out.println("服务器套接字已经创建成功");

         while (true) {// 如果套接字是连接状态

            System.out.println("等待客户级的连接");

            socket = server.accept();// 实例化Socket对象

            reader = new BufferedReader(new InputStreamReader(

                   socket.getInputStream()));// 实例化BufferedReader对象

            getClientMessage();// 调用getClientMessage()方法

         }

      } catch (Exception e) {

         // TODO Auto-generated catch block

         e.printStackTrace();

      }

   }

   private void getClientMessage() {

      try {

         while (true) {// 如果套接字是连接状态

            // 获得客户端信息

            System.out.println("客户机:" + reader.readLine());

         }

      } catch (Exception e) {

         // TODO Auto-generated catch block

         e.printStackTrace();

      }

      try {

         if (reader != null) {

            reader.close();// 关闭流

         }

         if (socket != null) {

            socket.close();// 关闭套接字

         }

      } catch (Exception e) {

         // TODO: handle exception

         e.printStackTrace();

      }

   }

   public static void main(String[] args) {

      MyTcp tcp = new MyTcp();// 创建本类对象

      tcp.getsever();// 调用方法

   }

}

服务器运行结果:

先运行服务端程序,等输出提示信息,等待客户连接;再运行客户端程序。

以下是客户端程序代码:

public class MyClien extends JFrame {

   private static final long serialVersionUID = 1L;

   private PrintWriter writer;

   Socket socket;

   private JTextArea ta = new JTextArea();

   private JTextField tf = new JTextField();

   Container cc;

   public MyClien(String title) {

      super(title);

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      cc = this.getContentPane();

      final JScrollPane scrollPane = new JScrollPane();

      scrollPane.setBorder(new BevelBorder(BevelBorder.RAISED));

      getContentPane().add(scrollPane, BorderLayout.CENTER);

      scrollPane.setViewportView(ta);

      cc.add(tf, "South");

      tf.addActionListener(new ActionListener() {

         // 绑定事件

         @Override

         public void actionPerformed(ActionEvent e) {

            // 将文本框中的信息写入流

            writer.println(tf.getText());

            // 将文本框中的信息显示在文本域中

            ta.append(tf.getText() + '\n');

            ta.setSelectionEnd(ta.getText().length());

            tf.setText("");

         }

      });

   }

   private void connect() {

      ta.append("尝试连接\n");

      try {

         socket = new Socket("127.0.0.1", 8998);

         writer = new PrintWriter(socket.getOutputStream(), true);

         ta.append("完成连接\n");

      } catch (Exception e) {

         e.printStackTrace();

      }

   }

   public static void main(String[] args) {

      MyClien clien = new MyClien("向服务器发送数据");

      clien.setSize(300, 300);

      clien.setVisible(true);

      clien.connect();

   }

}

客户端运行结果:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值