JAVA socket编程学习笔记

Socket是网络编程,而不是简单的网页编程,它与J2EE编写网页代码还是有很大的区别的,Socket更接近底层一点,所以难度稍稍大一点。

 

编写一个群发的demo,该例子是在《疯狂JAVA中找的》

 

server端:

package hb.thread.server;

import java.io.*;
import java.net.*;

//负责处理每个线程通信的线程类
public class ServerThread implements Runnable 
{
	//定义当前线程所处理的Socket
	Socket s = null;
	//该线程所处理的Socket所对应的输入流
	BufferedReader br = null;
	public ServerThread(Socket s)
		throws IOException
	{
		this.s = s;
		//初始化该Socket对应的输入流
		br = new BufferedReader(new InputStreamReader(s.getInputStream()));
	}
	public void run()
	{
		try
		{
			String content = null;
			//采用循环不断从Socket中读取客户端发送过来的数据
			while ((content = readFromClient()) != null)
			{
				//遍历socketList中的每个Socket,
				//将读到的内容向每个Socket发送一次——群发
				for (Socket s : MyServer.socketList)
				{
					PrintStream ps = new PrintStream(s.getOutputStream());
					ps.println("server thread : " + content);
				}
			}
		}
		catch (IOException e)
		{
			//e.printStackTrace();
		}
	}
	//定义读取客户端数据的方法
	private String readFromClient()
	{
		try
		{
			return br.readLine();	
		}
		//如果捕捉到异常,表明该Socket对应的客户端已经关闭
		catch (IOException e)
		{
			//删除该Socket。
			MyServer.socketList.remove(s);
		}
		return null;
	}
}

 

package hb.thread.server;

import java.net.*;
import java.io.*;
import java.util.*;

public class MyServer {
	// 定义保存所有Socket的ArrayList
	public static ArrayList<Socket> socketList = new ArrayList<Socket>();

	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(30000);
		while (true) {
			// 此行代码会阻塞,将一直等待别人的连接
			Socket s = ss.accept();
			socketList.add(s);
			// 每当客户端连接后启动一条ServerThread线程为该客户端服务
			new Thread(new ServerThread(s)).start();
		}
	}
}

 

客户端

package hb.thread.client;

import java.io.*;
import java.net.*;
import java.util.*;

public class ClientThread implements Runnable {
	// 该线程负责处理的Socket
	private Socket s;
	// 该现成所处理的Socket所对应的输入流
	BufferedReader br = null;

	public ClientThread(Socket s) throws IOException {
		this.s = s;
		br = new BufferedReader(new InputStreamReader(s.getInputStream()));
	}

	public void run() {
		try {
			String content = null;
			// 不断读取Socket输入流中的内容,并将这些内容打印输出
			while ((content = br.readLine()) != null) {
				System.out.println("-----------------------");
				System.out.println("-----------------------" + content.length());
				System.out.println(content);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("-----------run------------");
	}
}

 

package hb.thread.client;

import java.net.*;
import java.io.*;

public class MyClient {
	public static void main(String[] args) throws IOException {
		Socket s = s = new Socket("127.0.0.1", 30000);
		// 客户端启动ClientThread线程不断读取来自服务器的数据
		new Thread(new ClientThread(s)).start();
		// 获取该Socket对应的输出流
		PrintStream ps = new PrintStream(s.getOutputStream());
		String line = null;
		// 不断读取键盘输入
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		// readLine()方法是阻塞式的方法,当用户输入回车之后,会继续等待用户输入
		while ((line = br.readLine()) != null) {
			// 将用户的键盘输入内容写入Socket对应的输出流
			ps.println(line);
		}

		System.out.println("end");
	}
}

 

 

注意事项:

1、在Socket编程中,端口号尽量选择1024之后的端口号,因为在这之前很多端口号可能被很多知名的协议或者是网站占用了,所以为了降低冲突,选择不常用的端口号
2、TCP和UDP都有65535个端口,也就是说tcp 80 和 UDP 80端口是不一致的
3、client和server这两个只针对TCP协议而言,UDP协议是没有这个说法的,因为UDP只关注发送不管是否对方接收
4、server和client两端都可以读和写数据流,只有一端写了之后另一端才能读,我这样强调的目的是为了说明读写是有顺序的

你可能感兴趣的:(java,J2EE)