Scoket:TCP通讯模型
 
Socket编程模型是Java网络编程的基础,在Socket API的基础上,可以做出更多的网络应用程序,比如FTP、HTTP、QQ等通讯工具都可以通过Socket API来实现。
 
一、最简单的Socket编程模型:
 
package lavasoft.ex1;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
* 最简单的ScoketServer
*
* @author leizhimin 2009-11-20 21:54:37
*/

public class TestServer {
        public static void main(String[] args) throws IOException {
                ServerSocket ss = new ServerSocket(9999);
                while (true) {
                        System.out.println("------------");
                        Socket s = ss.accept();
                        System.out.println(s.getLocalPort() + " " + s.getPort() + " " + s.getLocalAddress().getHostAddress());
                        System.out.println(s.getInetAddress().getHostAddress() + ":" + s.getPort() + "客户端已经连接上了服务端ServerSocket!");
                }
        }
}
 
import java.io.IOException;
import java.net.Socket;

/**
* 最简单的Socket
*
* @author leizhimin 2009-11-20 22:04:40
*/

public class TestClient {
        public static void main(String[] args) throws IOException {
                for (int i = 0; i < 5; i++) {
                        Socket s = new Socket("192.168.1.101", 9999);
                        s.close();
                }
        }
}
 
先启动服务端,然后再启动客户端。
服务端的控制台显示:
------------
9999 1863 192.168.1.101
192.168.1.101:1863客户端已经连接上了服务端ServerSocket!
------------
9999 1864 192.168.1.101
192.168.1.101:1864客户端已经连接上了服务端ServerSocket!
------------
9999 1865 192.168.1.101
192.168.1.101:1865客户端已经连接上了服务端ServerSocket!
------------
9999 1866 192.168.1.101
192.168.1.101:1866客户端已经连接上了服务端ServerSocket!
------------
9999 1867 192.168.1.101
192.168.1.101:1867客户端已经连接上了服务端ServerSocket!
------------
 
客户端的没有输出。
 
二、服务端向客户端发送数据,客户端接收数据
 
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
* 向客户端发送数据
*
* @author leizhimin 2009-11-21 0:28:42
*/

public class TestServer {
        public static void main(String[] args) throws IOException {
                ServerSocket ss = new ServerSocket(9999);
                while (true) {
                        System.out.println("--------------server端------------");
                        Socket s = ss.accept();
                        DataOutputStream dos = new DataOutputStream(s.getOutputStream());
                        System.out.println("客户端[" + s.getInetAddress().getHostAddress() + ":" + s.getPort() + "]已经连接!");
                        dos.writeUTF("服务端写入客户端的数据:客户端[" + s.getInetAddress().getHostAddress() + ":" + s.getPort() + "]已经连接上服务端[" + s.getLocalAddress().getHostAddress() + ":" + s.getLocalPort() + "]!");
                        dos.flush();
                        dos.close();
                        s.close();
                }
        }
}
 
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;

/**
* 客户端接收服务端数据
*
* @author leizhimin 2009-11-21 0:28:53
*/

public class TestClient {
        public static void main(String[] args) throws IOException {
                System.out.println("--------------client端------------");
                for (int i = 0; i < 5; i++) {
                        Socket s = new Socket("192.168.1.101", 9999);
                        DataInputStream dis = new DataInputStream(s.getInputStream());
                        System.out.println("客户端接收的服务端数据:" + dis.readUTF());
                        dis.close();
                        s.close();
                }
        }
}
 
服务端控制台:
--------------server端------------
客户端[192.168.1.101:1868]已经连接!
--------------server端------------
客户端[192.168.1.101:1869]已经连接!
--------------server端------------
客户端[192.168.1.101:1870]已经连接!
--------------server端------------
客户端[192.168.1.101:1871]已经连接!
--------------server端------------
客户端[192.168.1.101:1872]已经连接!
--------------server端------------
 
客户端控制台:
--------------client端------------
客户端接收的服务端数据:服务端写入客户端的数据:客户端[192.168.1.101:1868]已经连接上服务端[192.168.1.101:9999]!
客户端接收的服务端数据:服务端写入客户端的数据:客户端[192.168.1.101:1869]已经连接上服务端[192.168.1.101:9999]!
客户端接收的服务端数据:服务端写入客户端的数据:客户端[192.168.1.101:1870]已经连接上服务端[192.168.1.101:9999]!
客户端接收的服务端数据:服务端写入客户端的数据:客户端[192.168.1.101:1871]已经连接上服务端[192.168.1.101:9999]!
客户端接收的服务端数据:服务端写入客户端的数据:客户端[192.168.1.101:1872]已经连接上服务端[192.168.1.101:9999]!

Process finished with exit code 0
 
三、两端同时读写数据
 
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
* 服务端先写后读数据
*
* @author leizhimin 2009-11-21 23:37:59
*/

public class TestServer {
        public static void main(String[] args) throws IOException {
                ServerSocket ss = new ServerSocket(9999);
                while (true) {
                        System.out.println("--------------server端------------");
                        Socket s = ss.accept();
                        DataInputStream dis = new DataInputStream(s.getInputStream());
                        DataOutputStream dos = new DataOutputStream(s.getOutputStream());
                        System.out.println("客户端[" + s.getInetAddress().getHostAddress() + ":" + s.getPort() + "]已经连接!");
                        dos.writeUTF("服务端写入客户端的数据:客户端[" + s.getInetAddress().getHostAddress() + ":" + s.getPort() + "]已经连接上服务端[" + s.getLocalAddress().getHostAddress() + ":" + s.getLocalPort() + "]!");
                        String _clientdata = null;
                        if ((_clientdata = dis.readUTF()) != null)
                                System.out.println("读取客户端发送的数据:" + _clientdata);
                        dis.close();
                        dos.flush();
                        dos.close();
                        s.close();
                }
        }
}
 
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

/**
* 客户端先读后写数据
*
* @author leizhimin 2009-11-21 23:43:05
*/

public class TestClient {
        public static void main(String[] args) throws IOException {
                System.out.println("--------------client端------------");
                for (int i = 0; i < 5; i++) {
                        Socket s = new Socket("192.168.1.101", 9999);
                        DataInputStream dis = new DataInputStream(s.getInputStream());
                        DataOutputStream dos = new DataOutputStream(s.getOutputStream());
                        String _serverdata = null;
                        if ((_serverdata = dis.readUTF()) != null)
                                System.out.println("客户端接收的服务端数据:" + _serverdata);
                        dos.writeUTF("[" + s.getLocalAddress().getHostAddress() + ":" + s.getLocalPort() + "]:Hello Server!");
                        dos.flush();
                        dos.close();
                        dis.close();
                        s.close();
                }
        }
}
 
服务端控制台:
--------------server端------------
客户端[192.168.1.101:1873]已经连接!
读取客户端发送的数据:[192.168.1.101:1873]:Hello Server!
--------------server端------------
客户端[192.168.1.101:1874]已经连接!
读取客户端发送的数据:[192.168.1.101:1874]:Hello Server!
--------------server端------------
客户端[192.168.1.101:1875]已经连接!
读取客户端发送的数据:[192.168.1.101:1875]:Hello Server!
--------------server端------------
客户端[192.168.1.101:1876]已经连接!
读取客户端发送的数据:[192.168.1.101:1876]:Hello Server!
--------------server端------------
客户端[192.168.1.101:1877]已经连接!
读取客户端发送的数据:[192.168.1.101:1877]:Hello Server!
--------------server端------------
 
客户端控制台:
--------------client端------------
客户端接收的服务端数据:服务端写入客户端的数据:客户端[192.168.1.101:1873]已经连接上服务端[192.168.1.101:9999]!
客户端接收的服务端数据:服务端写入客户端的数据:客户端[192.168.1.101:1874]已经连接上服务端[192.168.1.101:9999]!
客户端接收的服务端数据:服务端写入客户端的数据:客户端[192.168.1.101:1875]已经连接上服务端[192.168.1.101:9999]!
客户端接收的服务端数据:服务端写入客户端的数据:客户端[192.168.1.101:1876]已经连接上服务端[192.168.1.101:9999]!
客户端接收的服务端数据:服务端写入客户端的数据:客户端[192.168.1.101:1877]已经连接上服务端[192.168.1.101:9999]!

Process finished with exit code 0
 
 
注意:
对于TCP Socket程序,应该先启动Server,然后再启动Client。
对于发送接收数据,一定要注意读写的顺序,否则会发生相互等待的问题。