JAVA之Socket编程初步学习

本文介绍了一个基于 Java 的 Socket 服务器实现,该服务器能够处理多个客户端的同时连接请求,并为每个客户端分配独立的线程进行数据交换。文章还提供了一个简单的客户端示例,用于与服务器进行交互。

         在Java中,有三种套接字类:java.net.Socket、java.net.ServerSocket和DatagramSocket。其中Socket和ServerSocket类建立在TCP协议基础上,DatagramSocket类建立在UDP协议基础上。

       传输层向应用层提供了套接字Socket 接口,Socket 封装了下层的数据传输细节,应用层的程序通过Socket来建立与远程主机的连接以及进行数据传输。

 

      

 

    下面例子,模拟多个用户同时连接服务器,服务器收到一个客户连接申请时,就启动一个线程进行处理。

 

服务器类ServerSocketServer.java

package socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerSocketServer {
	public static void main(String[] args)throws Exception {
		new ServerSocketServer().service();
	}
	
	private int port=8888;//监听端口
	private ServerSocket serverSocket;
	public ServerSocketServer()throws Exception{
		serverSocket=new ServerSocket(port);
		System.out.println("服务器启动了.........");
	}
	public void service(){
		while(true){
			Socket socket=null;
			//进入阻塞,等待客户端的连接
			//如果客户端申请连接,则返回一个Socket对象,该对象和客户端的Socket对象构成一条通信渠道
			try {
				socket=serverSocket.accept();
				new SocketThread(socket).start();//有一个客户申请连接,就启动一个线程进行处理(可以考虑用线程池管理)
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	static class SocketThread extends Thread{
		private Socket socket=null;
		public SocketThread(Socket socket){
			this.socket=socket;
		}
		public void run(){
			try {
				String user=socket.getInetAddress()+":"+socket.getPort();
				System.out.println("新客户到来:"+user);
				//读取客户端发送类的内容
				BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
				//向客户端发送信息
				PrintWriter writer=new PrintWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8"));
				
				while(true){
				    String content=reader.readLine();
				    if(content==null) break;
					System.out.println("客户端"+user+"对服务器说:"+content);
					//服务器向客户端发送信息
					//所以必须使用println()输出
					//如果用print输出,则content必须加\r\n(content+"\r\n"),否则客户端的readLine()会无法读取,一直阻塞
				//	writer.print(content+"\r\n");//原样发回
					writer.println(content);
					writer.flush();
					if("bye".equalsIgnoreCase(content)) 
						break;//结束通信
				}
				reader.close();
				writer.close();
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				if(socket!=null)
					try {
						socket.close();
					} catch (IOException e) {
						e.printStackTrace();
					}//通信结束
			}
			
		}
	}
}


客户端类ClientSocket.java

 

package socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

public class ClientSocket {
	public static void main(String[] args)throws Exception {
		new ClientSocket().talk();
	}
	private String host="localhost";
	private int port=8888;
	private Socket socket;
	public ClientSocket()throws Exception{
		socket=new Socket(host,port);
	}
	private void talk(){
		try {
			//从键盘接收输入(输入是中文的话,就乱码了,估计和OS的字符集有关)
			BufferedReader readerLocal=new BufferedReader(new InputStreamReader(System.in,"UTF-8"));
			//从服务器接收信息
			BufferedReader readerServer=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
			//向服务器发送
			PrintWriter writer=new PrintWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8"));

			while(true){
				System.out.print("客户端往服务器发送信息:");
				String msg=readerLocal.readLine();//接收来自键盘的内容
				if(msg==null || "".equalsIgnoreCase(msg)) break;
				//服务器使用BufferedReader中的readLine()读取的
				//所以必须使用println()输出
				//如果用print输出,则msg必须加\r\n(msg+"\r\n"),否则服务器的readLine()会无法读取,一直阻塞
				//writer.print(msg+"\r\n");
				writer.println("bye".equalsIgnoreCase(msg)?msg:(msg+"好"));//加个"好"字,是为了测试socket传输中文是否正常,结论正常
				writer.flush();
				System.out.println("客户端接收到来自服务器的信息:"+readerServer.readLine());
				if("bye".equalsIgnoreCase(msg))
					break;
			}
			readerLocal.close();
			readerServer.close();
			writer.close();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			if(socket!=null){
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
				
		}
	}
}

 


1.启动服务器

2.启动客户端,发送内容a,bye

3.启动客户端,发送内容b,bye

   2,3是同时存在的

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值