Socket通常也称作“套接字”,用于描述IP地址和端口,可以用来实现不同虚拟机或不同计算机之间的通信。
——百度百科

套接字允许应用程序插入到网络中,并与插入到网络中的其他应用程序通信。
——《TCP/IP Socket编程·TCP/IP in C》

Socket编程示意图:

java tcp框架 java tcpip socket_System

服务器需要先启动,等待客户端连接。
客户端主动连接服务器,连接成功才能通信。

字节流版本

服务端:

import java.net.*;
import java.io.*;
public class Skt字节流S {
	public static void main(String[] args) {
		try {
			ServerSocket sSocket = new ServerSocket(8888);
			System.out.println("new ServerSocket");
			Socket s = sSocket.accept();
			System.out.println("accept()");
			InputStream is = s.getInputStream();
			OutputStream os = s.getOutputStream();
			byte[] b = new byte[1024];
			int len = is.read(b);
			String str = new String(b, 0, len);
			System.out.println("客户端说:" + str);
			os.write("对不起,我们这三碗不过岗".getBytes());
			is.close();
			os.close();
			s.close();
			sSocket.close();
			System.out.println("服务器端,OVER");
		} catch (Exception e) {
		}
	}
}

客户端:

import java.net.*;
import java.io.*;
public class Skt字节流C {
	public static void main(String[] args) {
		try {
			// Socket s = new Socket(InetAddress.getLocalHost() , 8888);
			Socket s = new Socket("127.0.0.1", 8888);
			InputStream is = s.getInputStream();
			OutputStream os = s.getOutputStream();
			os.write("你好,我要10碗酒,三斤牛肉".getBytes());
			byte[] b = new byte[1024];
			int len = -1;
			while ((len = is.read(b)) > 0) {
				String str = new String(b, 0, len);
				System.out.println("服务器端的回复:" + str);
			}
			is.close();
			os.close();
			s.close();
			System.out.println("客户端Over");
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

看效果时,可以一个程序用Eclipse启动,一个用cmd启动,编译时如果有错,可用如下语句:

javac -encoding utf-8  XXX.java

cmd运行程序时,不要有包名。


字符流版本

服务端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SktCharacterS {
	public static void main(String[] args) {
		try {
			ServerSocket sSocket = new ServerSocket(8888);
			Socket s = sSocket.accept();
			InputStream is = s.getInputStream();
			OutputStream os = s.getOutputStream();
			InputStreamReader isr = new InputStreamReader(is);
			BufferedReader bufR = new BufferedReader(isr);
			PrintWriter prtW = new PrintWriter(os);
			// -----------------------------------------------------
			String str = bufR.readLine();
			System.out.println("——" + str);
			prtW.print("你好,我是服务器");
			prtW.flush();
			bufR.close();
			isr.close();
			is.close();
			prtW.close();
			os.close();
			s.close();
			sSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

客户端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class SktCharacterC {
	public static void main(String[] args) {
		Socket s;
		try {
			s = new Socket(InetAddress.getLocalHost(), 8888);
			InputStream is = s.getInputStream();
			OutputStream os = s.getOutputStream();
			PrintWriter prtW = new PrintWriter(os);
			InputStreamReader isr = new InputStreamReader(is);
			BufferedReader bufR = new BufferedReader(isr);
			// --------------------------------------------------
			prtW.println("你好我是客户机");
			prtW.flush();
			String str = bufR.readLine();
			System.out.println("——" + str);
			bufR.close();
			isr.close();
			is.close();
			prtW.close();
			os.close();
			s.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

socket发送文件(基本款)

服务端:

import java.net.*;
import java.io.*;
public class SktFileS {
	public static void main(String[] args) {
		try {
			ServerSocket sSocket = new ServerSocket(8888);
			Socket s = sSocket.accept();
			InputStream ips = s.getInputStream();
			FileOutputStream fos = new FileOutputStream("recv.png");
			byte[] b = new byte[1024];
			int nLen = -1;
			while (true) {
				nLen = ips.read(b);
				if (nLen == -1) {
					break;
				}
				fos.write(b, 0, nLen);
			}
			fos.close();
			ips.close();
			s.close();
			sSocket.close();
		} catch (Exception e) {
		} finally {
			System.out.println("服务器端,OVER");
		}
	}
}

客户端:

import java.net.*;
import java.io.*;
public class SktFileC {
	public static void main(String[] args) {
		try {
			Socket s = new Socket("127.0.0.1", 8888);
			OutputStream ops = s.getOutputStream();
			FileInputStream fis = new FileInputStream("send.png");
			byte[] b = new byte[1024];
			int nLength = -1;
			while ((nLength = fis.read(b)) > 0) {
				ops.write(b, 0, nLength);
			}
			fis.close();
			ops.close();
			s.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			System.out.println("客户端Over");
		}
	}
}

socket发送文件(带文件名)

服务端:

import java.net.*;
import java.io.*;
public class SktFileWithNameS {
	public static void main(String[] args) {
		try {
			ServerSocket sSocket = new ServerSocket(8888);
			Socket s = sSocket.accept();
			InputStream ips = s.getInputStream();
			InputStreamReader isr = new InputStreamReader(ips);
			BufferedReader br = new BufferedReader(isr);
			// 读取文件名
			FileOutputStream fos = new FileOutputStream("recv_" + br.readLine());
			// 读取文件
			byte[] b = new byte[1024];
			int nLen = -1;
			while (true) {
				nLen = ips.read(b);
				if (nLen == -1) {
					break;
				}
				fos.write(b, 0, nLen);
			}
			fos.close();
			ips.close();
			s.close();
			sSocket.close();
		} catch (Exception e) {
		} finally {
			System.out.println("服务器端,OVER");
		}
	}
}

客户端:

import java.net.*;
import java.io.*;
public class SktFileWithNameC {
	public static void main(String[] args) {
		try {
			Socket s = new Socket("127.0.0.1", 8888);
			// 输出流
			OutputStream ops = s.getOutputStream();
			PrintWriter pw = new PrintWriter(ops, true);
			// 文件读入
			String strFile = "send.png";
			File f = new File(strFile);
			FileInputStream fis = new FileInputStream(f);
			// 写文件名
			pw.println(f.getName());
			// 文件内容发送
			byte[] b = new byte[1024];
			int nLength = -1;
			while ((nLength = fis.read(b)) > 0) {
				ops.write(b, 0, nLength);
			}
			pw.close();
			fis.close();
			ops.close();
			s.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			System.out.println("客户端Over");
		}
	}
}