客户端与服务端的Socket通信

客户端:

public class Client {
	/*
	 * java.net.Socket
	 * 套接字,封装了TCP协议,使用它可以与远端计算机通讯
	 */
	private Socket socket;
	/*
	 * 定义构造方法,用来初始化客户端
	 */
	/*
	 * 实例化Socket时需要传入两个参数:
	 * 1:服务端计算机的地址信息(IP地址)
	 * 2:服务端计算机上运行的服务端应用程序申请的服务端口
	 * 
	 * 
	 * 通过IP可以找到服务端的计算机,通过端口可以连接到运行在服务端计算机上的服务端应用程序
	 * 
	 * 实例化Socket的过程就是连接服务端的过程,若服务端无响应,实例化过程会抛出异常
	 * 
	 * 端口号是一个整数,2字节内的整数0-65536
	 * 但3000以内的端口号不要使用,因为紧密的绑定着系统程序,和世界上流行的应用程序。
	 * 10000以上也很少被使用
	 */
	public Client() throws Exception{
		try {
			Scanner scanner=new Scanner(System.in);
			String str=scanner.nextLine();
			
			socket=new Socket(str,8088);//"176.195.107.86"
			System.out.println(str);
			System.out.println("连接上服务端!");
		} catch (Exception e) {
			//记录日志
			throw e;
		} 
	}
	public void start(){
		try{
			//用来获取用户输入
			Scanner scanner=new Scanner(System.in);
			
			/**
			 * Socket提供方法:
			 * OutputStream getOutputStream()
			 * 通过获取的输出流写出的数据就可以通过
			 * 网络发送给远端计算机,对于客户端而言远端就是服务器。
			 */
			OutputStream out=socket.getOutputStream();
			//String message="你好服务端";
			//byte[] data=message.getBytes("UTF-8");
			OutputStreamWriter osw=new OutputStreamWriter(out,"UTF-8");
			PrintWriter pw=new PrintWriter(osw,true);
			
			
			//接收客户端发送过来的消息的线程启动
			ServerHandler handler=new ServerHandler();
			Thread t=new Thread(handler);
			t.start();
			
			System.out.println("请开始聊天吧!");
			String message=null;
			long time=System.currentTimeMillis()-500;
			while(true){
				message=scanner.nextLine();
				if(System.currentTimeMillis()-time>=500){
					pw.println(message);
					time=System.currentTimeMillis();
				}else{
					System.out.println("你说话过快!");
					time=System.currentTimeMillis();
				}
				
			}
			
			//pw.close();
			
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {//程序入口方法,没有逻辑代码
		Client client;
		try {
			client = new Client();
			client.start();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("服务端启动失败");
		}

	
	}
	/**
	 * 该线程专门用来循环读取服务端发送过来的消息并输出
	 * 到客户端的控制台上
	 * @author live
	 *
	 */
	private class ServerHandler implements Runnable{
           
		public void run() {
			try{
				InputStream in=socket.getInputStream();
				InputStreamReader isr
								=new InputStreamReader(in,"UTF-8");
				BufferedReader br
								=new BufferedReader(isr);
				String message=null;
				while((message=br.readLine())!=null){
					System.out.println(message);
				}
				
				
			}catch(Exception e){
				
			}
		}
		
	}
}

服务端:

public class Server {
	/**
	 * 运行在服务端的ServerSocket主要负责两个工作:
	 * 1:向系统申请服务端口,客户端就是通过这个端口与服务端应用程序建立连接的。
	 * 2:监听服务端口,一旦客户端通过该端口尝试连接时,ServerSocket就会实
	 * 例化一个Socket与该客户端通讯。
	 */
	private ServerSocket server;
	//存放所有客户端的输出流,用于广播消息
	private List<PrintWriter> allOut;
	public Server() throws Exception{
		try{
			
			/**
			 * 实例化SeverSocket时需要指定服务端口,客户端就是通过这个端口与服务端建立连接的。
			 * 
			 * 该端口不能与系统其他程序申请的端口冲突,否则会抛出异常。
			 * address already in use
			 */
			server=new ServerSocket(8088);
			allOut=new ArrayList<PrintWriter>();
			
			
		}catch(Exception e){
			throw e;
		}
	}
	public void start(){
		try{
			/*
			 * ServerSocket提供方法:
			 * Socket accept()
			 * 该方法是一个阻塞方法,调用后会一致等待客户端的连接,一旦一个客户端
			 * 通过ServerSocket申请的端口建立连接,那么accept方法会返回一个
			 * Socket实例,通过该Socket实例可以与建立连接的客户端进行通讯
			 */
		while(true){
			System.out.println("等待客户端连接。。。。。。。。。");
			Socket socket=server.accept();
			System.out.println("一个客户端连接了");
			//启动一个线程来处理该客户端交互
			ClientHandler handler=
								new ClientHandler(socket);
			Thread t=new Thread(handler);
			
			t.start();
		   }
			
			
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		try{
			Server server=new Server();
			server.start();
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("服务端启动失败");
		}
	}
	/*
	 * 该线程任务是用于处理与指定客户端的交互工作。
	 */
	private class ClientHandler implements Runnable{
		//当前线程通过这个Socket与指定客户端交互
		private Socket socket;
		//该客户端的地址信息
		private String host;
		public ClientHandler(Socket socket){
			this.socket=socket;
			//通过Socket获取远端计算机地址信息
			InetAddress address=socket.getInetAddress();
			//获取IP地址的字符串形式
			host=address.getHostAddress();
		}
		public void run() {
			PrintWriter pw = null;
			try{
				/*
				 * Socket提供方法:
				 * InputStream getInputStream()
				 * 通过获取的输入流读取的字节就是来自远端发送过来的数据,对于服务端而言,
				 * 远端指的就是客户端。
				 */
				InputStream in=socket.getInputStream();
				InputStreamReader isr=new InputStreamReader(in,"UTF-8");
				
				BufferedReader br=new BufferedReader(isr);
				
				/*
				 * 通过Socket获取输出流,用于将消息发送给客户端
				 */
				OutputStream out=socket.getOutputStream();
				OutputStreamWriter osw=new OutputStreamWriter(out,"UTF-8");
				 pw=new PrintWriter(osw,true);
				//将该客户端的输出流存入共享集合
				
				synchronized (allOut) {//给allOut加锁,保证线程安全
					allOut.add(pw);
				}
				
				String message=null;
				/*
				 * 使用br.readline读取客户端发送过来的一行字符串时,该方法处于阻塞状态
				 * 直到客户端真实发送过来一行,这里才会返回
				 * 
				 * 但是当客户端断开连接时,br.readline会根据客户端不同操作系统有不同的反馈
				 * 当Windows的客户端断开,br.readline方法会抛出异常
				 * 当Linux的客户端断开,br.readline方法会返回null.			 
				 */
				while((message=br.readLine())!=null){
				//System.out.println(host+"说:"+message);
				/*//将读到的内容再回复给客户端(临时测试用)
				pw.println("回复:"+message);
				*/
					/*
					 * 将消息转发给所有客户端
					 */
					synchronized (allOut) {
					     for(PrintWriter o:allOut){
						     o.println(host+"说:"+message+"\n连接人数:"+allOut.size());
					       }
					}
					
				}
			}catch(Exception e){
				
			} finally {
                /*
                 * 当客户端断线,要将输出流从共享集合中删除
                 * 需要同步
                 * 
                 * 处理客户端断开连接的操作
                 */
				synchronized (allOut) {
					allOut.remove(pw);
				}
                try{
                	socket.close();
                }catch(IOException e){
                	e.printStackTrace();
                }
                
            }
		}
		
	}
	
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MFC(Microsoft Foundation Classes)是微软公司开发的一套面向对象的C++类库,用于开发Windows应用程序。在MFC中,客户端服务端socket是用来进行网络通信的重要组件。 客户端socket指的是在网络中发起连接的一方。在MFC中,可以使用CSocket类来创建和管理客户端socket。通过CSocket类的成员函数,可以实现与服务器的连接、发送和接收数据等操作。客户端socket可以向服务器发送请求,获取相应的数据或服务。 服务端socket则是接受客户端连接的一方。也是通过CSocket类来创建和管理服务端socket服务端socket可以监听端口,接受客户端连接请求,并与客户端建立通信服务端socket可以处理多个客户端的请求,提供相应的服务。 在使用MFC开发网络应用程序客户端服务端socket通常需要配合使用。客户端socket负责与服务端建立连接,并发送请求。服务端socket则负责接受客户端连接请求,并处理客户端的请求。通过socket编程,可以实现客户端服务端的数据交互,实现网络通信功能。 总结来说,MFC中的客户端服务端socket是实现网络通信的重要组件。通过客户端socket可以向服务器发送请求,获取相应的数据或服务。而服务端socket则接受客户端连接请求,并提供相应的服务。通过MFC提供的CSocket类,我们可以方便地创建、管理和控制这些socket,实现客户端服务端之间的数据交互。 ### 回答2: MFC是Microsoft Foundation Classes的缩写,它是微软公司为了简化Windows应用程序的开发而开发的一个类库。客户端服务端socket则是在网络编程中使用的两种角色。 在MFC中,我们可以使用MFC类库提供的相关类来实现客户端服务端socket通信客户端socket通常用于向服务器发送请求并接收服务器的响应。我们可以使用MFC的CAsyncSocket类来创建一个客户端socket对象,然后通过对象的方法来连接服务器、发送数据和接收数据。 服务端socket则是用于接收客户端的请求并提供相应的服务。我们可以使用MFC的CSocket类来创建一个服务端socket对象,通过对象的方法来绑定本地地址和端口、监听客户端连接请求、接收客户端发送的数据以及向客户端发送数据等操作。 在实际应用中,客户端服务端socket可以通过网络进行通信,比如TCP/IP协议。客户端通过连接服务端socket来发送请求和接收响应,而服务端socket则通过接收客户端连接来处理客户端的请求并提供相应的服务。 总之,MFC提供了方便易用的类库来实现客户端服务端socket通信,开发人员可以使用这些类库来快速开发网络应用程序。 ### 回答3: MFC是微软基于Windows操作系统的应用程序开发框架,提供了许多方便的类和函数,用于开发Windows图形用户界面应用程序。MFC中提供了用于创建和管理客户端服务端socket的类。 客户端socket用于建立与服务器的连接,并向服务器发送请求。在MFC中,可以使用CSocket类创建和管理客户端socket。CSocket类提供了一组方法,如Create、Connect、Send等,可以方便地创建一个客户端socket,并与服务器建立连接,发送数据到服务器。 服务端socket用于接受客户端连接请求,并处理客户端发送的数据。在MFC中,可以使用CSocket和CAsyncSocket类来创建和管理服务端socket。CSocket类提供了一个Accept方法,用于接受客户端连接请求,当有新的客户端连接,会触发一个Accept事件,开发者可以重写该事件处理函数来处理新的连接。CAsyncSocket类是一个异步的socket类,在服务端应用程序中常用于处理多个客户端连接和数据交互。 在MFC中,客户端服务端socket之间的通信可以通过发送和接收数据来实现。客户端可以使用Send方法发送数据到服务器,而服务端可以使用Send方法将数据发送给已连接客户端客户端服务端之间的数据交换可以使用字节流,也可以使用特定的通信协议,如HTTP、TCP/IP等。 总之,使用MFC的CSocket类和CAsyncSocket类可以方便地创建和管理客户端服务端socket,实现客户端与服务器之间的通信。通过发送和接收数据,可以实现数据的传输和交换。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值