TCP通信的几种方式

1.一个客户端与一个服务器连接客户端给服务器发送hello服务器端接收并打印

服务端

package com.an.test.tcp;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Server1 {
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(8888);
		Socket socket = ss.accept();
		System.out.println("一个客户端连接上...");
		
		InputStream in = socket.getInputStream();
		byte[] b = new byte[1024];
		int len = -1;
		StringBuilder sb = new StringBuilder();
		while((len = in.read(b))!=-1){
			sb.append(new String(b,0,len));
		}
		System.out.println(sb);
		
	}
	
}

客户端

package com.an.test.tcp;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class Client1 {
	public static void main(String[] args) throws Exception, IOException {
		Socket s = new Socket("127.0.0.1", 8888);   
		OutputStream out = s.getOutputStream();
		out.write("hello".getBytes());
		out.close();
		s.close();
	}
}


2.一个客户端与一个服务器连接,客户端给服务器发送hello,服务器端接收并打印,然后把hello逆转后返回,客户端接收服务器返回的消息,并打印

服务端

package com.an.test.tcp2;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.rmi.server.SocketSecurityException;

public class Server2 {
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(9999);
		Socket socket = ss.accept();
		
		InputStream in = socket.getInputStream();
		int len = -1;
		byte[] b = new byte[1024];
		StringBuilder sb = new StringBuilder();
		while((len = in.read(b))!=-1){//读到流末尾,以后再也不传数据
			sb.append(new String(b,0,len));
		}
		System.out.println(sb);
		
		//返回,想客户端传入数据
		OutputStream out = socket.getOutputStream();
		out.write(sb.reverse().toString().getBytes());
		
		//断开
		in.close();
		out.close();
	}
}

客户端

package com.an.test.tcp2;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client2 {
	public static void main(String[] args) throws Exception, IOException {
		Socket s = new Socket("127.0.0.1", 9999);
		OutputStream out = s.getOutputStream();
		
		out.write("hello".getBytes());//此时并没有写一个流末尾的标记,只有输出流关闭时,才会写一个流末尾的标记
		//out.close();//socket通道都关闭
		s.shutdownOutput();//只关闭输出流通道,不关闭输入流通道
		
		//就收服务器返回的内容
		InputStream in = s.getInputStream();
		byte[] b = new byte[1024];
		int len = -1;
		StringBuilder sb = new StringBuilder();
		while((len = in.read(b))!=-1){
			sb.append(new String(b,0,len));
		}
		System.out.println(sb);
		
		out.close();
		in.close();
		s.close();
	}
}

//Client:olleh
//Server:hello

3.一个客户端与一个服务器连接,客户端可以从键盘输入消息,然后发送给服务器端,输入一行发送一行,直到输入bye结束。服务器端接收到一行就打印,即实现一个客户端多次与服务器通信

服务端

package com.an.test.tcp3;

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

public class Server3 {
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(7777);
		Socket socket = ss.accept();
		InputStream in = socket.getInputStream();
		
	//字节流对去 -1结尾,不能用
	/*	int len = -1;
		byte[] b = new byte[1024];
		StringBuilder sb = new StringBuilder();
		while((len = in.read(b))!=-1){
			sb.append(new String(b,0,len));
		}
		System.out.println(sb);
		*/
		
		BufferedReader br = new BufferedReader(new InputStreamReader(in));
		String str;
		while((str = br.readLine())!=null){
			System.out.println(str);
		}
		
		in.close();
		ss.close();
	}
}

客户端

package com.an.test.tcp3;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class Client3 {
	public static void main(String[] args) throws Exception, IOException {
		Socket s = new Socket("127.0.0.1", 7777);
		
		OutputStream out = s.getOutputStream();
		
		Scanner in = new Scanner(System.in);
		
	//这里是循环输入,所以在服务端不能用字节来读取,要用字符流一行一行的读取
		//方法一
		/*while(true){
			String str = in.next();
			if(str.equals("bye")){
				break;
			}
			out.write((str+"\n").getBytes());
		}*/
		
		//方法2
		/*while(in.hasNextLine()){
			String str = in.nextLine();
			if(str.equals("bye")){
				break;
			}
			out.write((str+"\n").getBytes());
		}*/
		
		//方法3
		PrintStream ps = new PrintStream(out);
		while(in.hasNextLine()){
			String message = in.nextLine();
			ps.println(message);
			if(message.equals("bye")){
				break;
			}
		}
		
		out.close();
	}
}

4.多个客户端与一个服务器连接,客户端可以从键盘输入消息,然后发送给服务器端,输入一行发送一行,直到输入bye结束。服务器端接收到一行就打印。。即实现多个客户端多次与服务器通信

服务端

package com.an.test.tcp4;

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

public class Server4 {
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(6666);
		//服务器一直在监听客户端的连接,可以连接无数个
		while(true){
			//监听一个客户端的连接
			Socket socket = ss.accept();
			
			new Thread(){
				//一个线程要做的事,接受一个客户端的消息
				public void run() {
					//接受客户端的消息
					try(
							InputStream in = socket.getInputStream();
							BufferedReader br = new BufferedReader(new InputStreamReader(in));
							){
						String str;
						while((str=br.readLine())!=null){
							System.out.println(str);
						}
						
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				}
			}.start();
		}
		
	}
}

客户端

package com.an.test.tcp4;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class Client4 {
	public static void main(String[] args) throws Exception, IOException {
		Socket s = new Socket("127.0.0.1", 6666);
		
		OutputStream out = s.getOutputStream();
		Scanner in = new Scanner(System.in);
		PrintStream ps = new PrintStream(out);
		while(in.hasNextLine()){
			String str = in.nextLine();
			ps.println(str);
			if(str.equals("bye")){
				break;
			}
		}
		
		out.close();
		s.close();
		in.close();
		
	}
}

5.一个服务器负责维护多人聊天效果,即多个客户端同时在线聊天的效果


客户端要从键盘输入消息,给大家发(本质上是通过服务器转发的,因此它先发给服务器),直到bye结束


A客户端发送的消息,服务器收到后负责给B,C,D等所有在线客户端转发


A客户端同时可以发消息,也可以收消息,“同时”进行


服务器“同时”接受多个客户端的连接


服务端

package com.an.test.tcp5;

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;


public class Server5 {
	//记录所有在线人员
	private static ArrayList<Socket> online = new ArrayList<Socket>();
	public static void main(String[] args) throws IOException {
		//开启服务器
		ServerSocket ss = new ServerSocket(7979);
		while(true){
			Socket accept = ss.accept();
			
			//将上线成员添加到online中
			online.add(accept);
			
			sendOthers(accept,"上线啦!");
			
			//每一个客户端都要有单独的线程来维护通信
			new Thread(){
				public void run() {
					try(
							InputStream in = accept.getInputStream();
							BufferedReader br = new BufferedReader(new InputStreamReader(in));
							) {
						String str;
						while((str=br.readLine())!=null){
							System.out.println(str);
							//发给其他客户端
							sendOthers(accept,str);
							if(str.equals("bye")){
								break;
							}
						}
					} catch (Exception e) {
						//如果当前客户端通信异常
						//应该把当前客户端移除
						sendOthers(accept, "掉线啦!");
					}
					//从online中移除当前的客户端
					online.remove(accept);
				}
			}.start();
		}
		
	}
	private static void sendOthers(Socket self, String message){
		
		ArrayList<Socket> offline = new ArrayList<Socket>();
		String ip = self.getInetAddress().getHostAddress();//本客户端的IP地址
		
		//遍历所有的在线客户端
		for(Socket s:online){
			if(!s.equals(self)){//群发消息时,自己是收不到的,不是自己才能收到
				
				try{
					OutputStream out = s.getOutputStream();
					PrintStream ps = new PrintStream(out);
					if("bye".equals(message)){
						ps.println(ip+"下线了");
					}else{
						ps.println(ip+"说:"+message);
					}
				} catch (IOException e) {
					offline.add(s);
				}
			}
		}
		for(Socket s:offline){
			online.remove(s);
		}
		
	}
}

客户端

package com.an.test.tcp5;

import java.io.BufferedInputStream;
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.Socket;
import java.net.SocketException;
import java.util.Scanner;

public class Client5 {
	public static void main(String[] args) throws Exception, IOException {
		Socket socket = new Socket("127.0.0.1", 7979);
		// 2.收消息和发消息是“同时”进行的
		// 发消息要一个线程维护,收消息也要一个线程维护
		
		// 发消息
		Thread t = new Thread() {
			public void run() {
				try (	Scanner input = new Scanner(System.in);
						OutputStream out = socket.getOutputStream();
						PrintStream ps = new PrintStream(out);) {
					while (input.hasNextLine()) {
						String str = input.nextLine();
						ps.println(str);
						if (str.equals("bye")) {
							break;
						}
					}
				} catch (Exception e) {
					return;
				}

			}
		};
		t.start();
		
		new Thread(){
			//负责收消息
			public void run() {
				try (
						InputStream in = socket.getInputStream();
						BufferedReader br = new BufferedReader(new InputStreamReader(in));
						){
					String str;
					while((str=br.readLine())!=null){
						System.out.println(str);
					}
				}catch(SocketException e){
					return ;
				} catch (IOException e) {
					// TODO Auto-generated catch block
					return;
				}
			}
		}.start();
		
		t.join();
		socket.close();
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值