Java网络编程之Socket编程

1.1Socket编程的一般步骤

使用Socket进行通讯的一般连接过程:服务端监听某个端口是否有连接请求,客服端想服务端发出连接请求,服务端向客户端发回接收消息这样就建立一个连接。服务端和客户端都可以通过发送、写入等方法与对方通信。

Socket工作过程包含以下四个基本的步骤:

  1. 创建Socket
  2. 打开连接到Socket的输入/输出流
  3. 按照一定的协议对Socket进行读/写操作
  4. 关闭Socket

客服端与服务器端的通讯步骤

客服端与服务器端的通讯步骤

1.2    Socket服务端编程

在服务器端程序编程中,第一步是监听端口,也就是监听是否有客服端连接到达。实现服务器端监听的代码如下:

ServerSocket ss = new ServerSocket (int port);
服务器端编程的第二步是获得连接。实现获得连接的代码:

Socket socket = ss.acept();
最后,在服务器端通信完成以后,关闭服务器端连接:

Socket服务器端编程示例:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
	public static void main(String[] args) {
		ServerSocket ss = null;//服务器端
		Socket s = null;//客服端
		InputStream in = null;//输入流
		OutputStream out = null;//输出流
		//没有下面的对输入流和输出流进行包装,只能输入一个字符,就会马上从服务器端返回数据
		BufferedReader reader = null;//缓冲流
		PrintStream print=null;//输出流
		try {
			//服务端建立连接,端口号为10000
			ss= new ServerSocket(10000);
			//服务器端接受客户端的请求
			s=ss.accept();
			//从客户端获取输入流,用于读取用户端数据
			in=s.getInputStream();
			//想客服端写东西
			out=s.getOutputStream();
			reader=new BufferedReader(new InputStreamReader(in));
			print = new PrintStream(out);
			/*//这是只能输入一个字符,就会马上从服务器端返回数据的代码,没有经过输入流和输出流包装
			byte[] b = new byte[1024];
			int len = in.read(b);
			String clientStr = new String(b, 0, len);
			String outputStr=clientStr+",您好!";
			out.write(outputStr.getBytes());*/
			String clientStr;
			//使用循环,解决每当客服端程序输入一句话按返回键后服务端就结束的问题
			while (!(clientStr = reader.readLine()).equalsIgnoreCase("exit")) {
				String outputStr = clientStr+"您好!";
				print.println(outputStr);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				out.close();
				in.close();
				s.close();
				ss.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
服务器端启动以后,可以使用Windows自带的telnet命令,检测写的服务器端程序是否正常。在命令行输入telnet localhost 10000,localhost是指本机,127.0.0.1也是代表本地。

上面程序还有一个致命问题,只能启动一个客服端,只实现了一个客服端的通讯。修改代码如下:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Server2 {
	private List<Socket> sockets = new ArrayList<Socket>();

	public static void main(String[] args) {
		new Server2().startServer();
	}

	public void startServer() {
		ServerSocket ss = null;// 服务器端
		try {
			// 服务端建立连接,端口号为10000
			ss = new ServerSocket(10000);
			while (true) {
				// 服务器端接受客户端的请求
				Socket s = ss.accept();// ServerSocket.accept此方法在连接接入之前一直阻塞。
				sockets.add(s);
				// 启动一个线程
				new Start(s).start();
				// new Server2().new Start(s).start();
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class Start extends Thread {
		Socket s = null;// 客服端
		InputStream in = null;// 输入流
		// 没有下面的对输入流和输出流进行包装,只能输入一个字符,就会马上从服务器端返回数据
		BufferedReader reader = null;// 缓冲流

		public Start(Socket _socket) {
			this.s = _socket;
		}

		@Override
		public void run() {

			try {
				// 从客户端获取输入流,用于读取用户端数据
				in = s.getInputStream();
				// 想客服端写东西
				reader = new BufferedReader(new InputStreamReader(in));
				// 使用循环,解决每当客服端程序输入一句话按返回键后服务端就结束的问题
				// 客户端可以不断的输入,知道接收到exit服务器不在回复
				out: while (true) {
					String clientStr = reader.readLine();
					String outputStr = clientStr + "您好!";
					for (Socket socket : sockets) {
						if (clientStr.equalsIgnoreCase("exit")) {
							System.out.println(sockets.size() + "——eee——" + s
									+ "次用户已被删除");
							sockets.remove(s);
							break out;
						}
						System.out
								.println(sockets.size() + "--------" + socket);
						OutputStream out = socket.getOutputStream();// 输出流
						PrintStream print = new PrintStream(out);// 输出流
						print.println(outputStr);
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					in.close();
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}
	}

}






































  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值