Java的Socket网络编程

最近做一个手机APP项目,要用到TCP Socket。因为我不会Android或IOS的原生开发,所以选择了uni-app这个里用HTML5技术做APP的技术框架,但uni-app并未封装对原生TCP Socket的支持(支持HTTP,WebSocket就足够大多数APP使用了),所以,需要用到Native.js(框架支持Native.js,一般使用HTML5技术做APP的框架都支持)调用android原生接口,也可以调用android自带的java库。
本文仅介绍Java的Socket编程。我们正式开始。
服务器端先建立监听套接字服务,然后在无限循环里等待连接过来,来一个连接以后,创建一个线程来为这个套接字服务,方式也很直接,接收信息后原样返回。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;

public class SocketServer {
	public static void main(String[] args) throws IOException{
		//创建Socket
		@SuppressWarnings("resource")
		ServerSocket listenSocket = new ServerSocket(10000);
		System.out.println("服务器正在监听...");
		//等待连接的Socket,他在等生成实例,生成了便说明有连接成功了
		Socket socket ;
		while(true) {
			socket = listenSocket.accept();
			System.out.println("有新连接到来,端口号为" + socket.getPort());
			//每接收到一个客户端连接刚创建一个线程来处理该连接的情况
			Thread thread = new Thread(new MyRunnable(socket));
			thread.start();
		}
	}
}

//创建一个内部类来为每个连接处理线程情况
class MyRunnable implements Runnable{
	Socket socket;

	public MyRunnable(){ }

	public MyRunnable(Socket socket){
		this.socket = socket;
	}

	@Override
	public void run() {
		if(socket == null ){
			return ;
		}
		InputStream inStream   = null;
		BufferedReader bufferReader = null;
		OutputStream outStream = null;
		PrintWriter pintWriter = null;
		try {
			inStream = socket.getInputStream();
			outStream = socket.getOutputStream();
			bufferReader = new BufferedReader(new InputStreamReader(inStream));
			pintWriter = new PrintWriter(outStream);
			String text = new String();
			while (true) {
				text = bufferReader.readLine();
				if (text == null) {
					System.out.println("客户端已断开");
					break;
				}
				if (text.isEmpty() || text == "exit") {
					break;
				}

				System.out.println("收到:" + text);

				// 将消息原样返回给客户端
				System.out.println("发送:" + text);
				pintWriter.write(text + "\n");
				pintWriter.flush();
			}
			//关闭接收数据
			socket.shutdownInput();            
			//关闭输出流
			socket.shutdownOutput();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//关闭所在资源(与创建反序)            
			try {
				pintWriter.close();
				outStream.close();
				bufferReader.close();
				inStream.close();
				if(null != socket)  {
					socket.close();     
				}                   
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}            
		}                                
	}
}

客户端则建立连接后无限循环发送信息,然后接收服务器反馈回来的信息(这是大多数业务的场景),直到输入exit断开连接。

import java.util.Scanner;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class SocketClient {

	public static void main(String[] args) throws UnknownHostException, IOException {
		connectServer();
	}

	/**
	 * 建立Socket 连接方法
	 * @param num
	 * @param msg
	 */
	public static void connectServer() {
		BufferedReader bufferReader = null;
		InputStream inStream = null;
		PrintWriter printWriter = null;
		OutputStream outStream = null;
		Socket socket = null ;
		Scanner input = new Scanner(System.in);
		try{
			String address = "localhost";
			int  port = 10000;
			System.out.println("连接服务器...");
			socket = new Socket(address, port);
			inStream = socket.getInputStream();
			outStream = socket.getOutputStream();
			bufferReader = new BufferedReader(new InputStreamReader(inStream));
			printWriter = new PrintWriter(outStream);
			String text;
			while (true) {
				System.out.println("请输入要发送的内容并回车:");
				text = input.nextLine();
				if (text == "exit") {
					break;
				}
				System.out.println("发送:" + text);
				printWriter.write(text + "\n");
				printWriter.flush();
				System.out.println("已发送");

				text = bufferReader.readLine();
				if (text == null) {
					System.out.println("服务器断开");
					break;
				}
				System.out.println("收到:" + text);
			}
		} catch(IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bufferReader.close();
				printWriter.close();
				inStream.close();
				if(null != socket)  {
					socket.shutdownOutput();
					socket.close();     
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

附上Java的API手册地址:https://docs.oracle.com/javase/8/docs/api/

这里要说明的是:实际项目中,服务器端要考虑客户端的超时退出,以防止客户端连上来以后断网了,然后客户端关机了的情况导致服务器维护多个无效连接。
客户端也同理要考虑自己断网后用户还在操作的情况。
所以建议用 setSoTimeout 方法设置SO_TIMEOUT的时间,使读接口不会一直阻塞。
在用Linux C编程里,也要考虑这些事情的。这个跟TCP协议有关系。

附:本文代码源自网址:网络编程:Java Socket通信实现(一)这篇文章,感谢作者的代码示例。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值