手把手教你 Socket 通信(TCP/IP)

导读 本文将给出完整 Socket 通信代码,在 eclipse 中亲测有效。在Android Studio中用Java开发也是一样的,只是把代码和控件搭配一下,注册监听就好。

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

建立网络通信连接至少要一对端口号(socket)。socket 本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。

下载eclipse:

https://www.eclipse.org/

本文将给出完整 Socket 通信代码,在 eclipse 中亲测有效。在Android Studio中用Java开发也是一样的,只是把代码和控件搭配一下,注册监听就好。区别就是在 AS 中 import 的声明不太一样,然后窗口不需要自己建立。

效果如图:

手把手教你 Socket 通信(TCP/IP)手把手教你 Socket 通信(TCP/IP)

在eclipse中,File→New→Java Project→起个英文名字→Finish(我起的名字是TCP)

目录结构:

手把手教你 Socket 通信(TCP/IP)手把手教你 Socket 通信(TCP/IP)

新建完以后有个src默认包,右键 src→New→Package→ 输入 com.net(因为程序里我用的包的名字是这个,你可以同时两个一起改)→ Finish

然后右键 com.net → New → Class → 输入 TCPClient(因为我程序里面用的这个类名称)

然后右键 com.net → New → Class → 输入 TCPServer(因为我程序里面用的这个类名称)

两个里面分别粘贴代码:

TCPServer
package com.net; 
 
import java.io.*; 
import java.net.*; 
import java.awt.*; 
import java.awt.event.*; 
 
public class TCPServer { 
 static DataInputStream dis=null; 
 public static void main(String[] args){ 
  boolean started=false; 
  Socket s=null; 
  TextArea ta=new TextArea(); 
  ta.append("从客户端接受的数据:"+"\n"); 
  ServerSocket ss=null; 
  try{ 
   ss=new ServerSocket(8866);                       //端口号 
  }catch(BindException e){ 
   System.exit(0); 
  }catch(IOException e){ 
   e.printStackTrace(); 
  } 
  Frame f=new Frame("服务器端");              //窗体名称  
  f.setLocation(300, 300);           //窗体出现位置 
  f.setSize(200, 200);            //窗体大小 
  f.add(ta,BorderLayout.NORTH); 
  f.pack(); 
  f.addWindowListener(new WindowAdapter(){ 
   public void windowClosing(WindowEvent e){ 
    System.exit(0); 
   } 
  }); 
  f.setVisible(true); 
  try{               //try-catch块捕捉异常 
   started=true; 
   while(started){ 
    boolean bConnected=false; 
    s=ss.accept(); 
    bConnected=true; 
    dis=new DataInputStream(s.getInputStream()); 
    while(bConnected){ 
        String str=dis.readUTF(); 
        ta.append(str+"\n"); 
    } 
   } 
  }catch(EOFException e){                                  
   System.out.println("Client closed!"); 
  }catch(IOException e){ 
   e.printStackTrace(); 
  }finally{ 
   try{ 
    if(dis!=null) 
     dis.close(); 
    if(s!=null) 
     s.close(); 
   }catch(Exception e){ 
    e.printStackTrace(); 
   } 
  } 
 } 
}
TCPClient
package com.net; 
import java.awt.*; 
import java.awt.event.*; 
import java.io.*; 
import java.net.*; 
 
public class TCPClient extends Frame{ 
 Socket s=null; 
 DataOutputStream dos=null; 
 DataInputStream  dis=null; 
 TextField tf=new TextField(40); 
 List list=new List(6); 
 public static void main(String[] args){ 
  TCPClient client=new TCPClient(); 
  client.list.add("向服务器端发送的数据:"); 
  client.setTitle("客户端"); 
  client.run(); 
 } 
 public void run(){ 
  setLocation(400,300); 
  this.setSize(300, 300); 
  add(tf,BorderLayout.SOUTH); 
  add(list,BorderLayout.NORTH); 
  pack(); 
  this.addWindowListener(new WindowAdapter(){ 
   public void windowClosing(WindowEvent e){ 
    disconnect(); 
    System.exit(0); 
   } 
  }); 
  tf.addActionListener(new MyListener()); 
  setVisible(true); 
  connect(); 
 } 
public void connect(){ 
 try{ 
  s=new Socket("127.0.0.1",8866); 
  dos=new DataOutputStream(s.getOutputStream()); 
 }catch(UnknownHostException e){ 
  e.printStackTrace(); 
 }catch(IOException e){ 
  e.printStackTrace(); 
 } 
} 
public void disconnect(){ 
 try{ 
  dos.close(); 
  s.close(); 
 }catch(IOException e){ 
  e.printStackTrace(); 
 } 
} 
private class MyListener implements ActionListener{ 
    public void actionPerformed(ActionEvent e){ 
      String s1=null; 
      String s2=null; 
      String str=tf.getText().trim(); 
      list.add(str); 
      tf.setText(""); 
      try{ 
       dos.writeUTF(str); 
       dos.flush(); 
      }catch(IOException e1){ 
         e1.printStackTrace();   
      } 
      } 
    } 
}

然后先运行服务器,再运行客户端,否则会报错,因为Socket通信本质是先打开服务器监听端口。然后就会出现效果图。

本机回环 IP 是 127.0.0.1,你可以改为其他 IP 地址,即可实现跨机 Socket 通信。

原文来自: https://www.linuxprobe.com/socket-tcp-ip.html

请使用浏览器的分享功能分享到微信等