java 单线程之tcp_Java中网络编程之TCP协议

一、TCP的基本概念

TCP是专门设计用于在不可靠的英特网上提供可靠的、端到端的字节流通信的协议,是一个面向连接的协议,TCP连接是字节流而非报文流。UDP和TCP各有65536个端口号互不影响。

二、单线程服务端

以下代码只能实现服务端和客户端的同步对话。服务端处理完一个客户端请求,才会处理另一个客户端请求。服务器端的输出效果是Client1阻塞20秒,Client2不会执行。必须等Client1阻塞结束之后,Client2才会执行。该例子可用来学习TCP的基本语法。

/**

* TCP客户端1

*

* @author 徐越

*

*/

publicclassClient1

{

publicstaticvoidmain(String[] args)throwsException

{

Socket socket =newSocket("127.0.0.1",8821);

OutputStream os = socket.getOutputStream();

String msg ="我是徐越1";

Thread.sleep(20000);

os.write(msg.getBytes());

os.flush();

os.close();socket.close();

}

}

/**

* TCP客户端2

*

* @author 徐越

*

*/

publicclassClient2

{

publicstaticvoidmain(String[] args)throwsException

{

Socket socket =newSocket("127.0.0.1",8821);

OutputStream os = socket.getOutputStream();

String msg ="我是徐越2";

os.write(msg.getBytes());

os.flush();

os.close();socket.close();

}

}

/**

* 单线程TCP服务端

*

* @author 徐越

*

*/

publicclassServer

{

publicstaticvoidmain(String[] args)throwsException

{

// 创建端口为8821的TCP服务器端对象

// 8821是服务器端的端口号而客户端从某端口A连到8821,端口A是随机的

ServerSocket serverSocket =newServerSocket(8821);

while(true)

{

// 若无客户端发送请求则线程在此阻塞,方法不继续执行

Socket socket = serverSocket.accept();

System.out.println("connected");

InputStream instream = socket.getInputStream();

ByteArrayOutputStream bos =newByteArrayOutputStream();

intlen =0;

byte[] buffer =newbyte[1024];

while((len = instream.read(buffer)) != -1)

{

bos.write(buffer,0, len);

}

instream.close();

bos.flush();

bos.close();

String msg = bos.toString();

System.out.println("客户端的IP:"+ socket.getInetAddress().getHostAddress());

System.out.println("客户端的端口:"+ socket.getPort());

System.out.println("客户端的信息:"+ msg);

}

}

}

执行结果

connected

客户端的IP:127.0.0.1

客户端的端口:3775

客户端的信息:我是徐越1

connected

客户端的IP:127.0.0.1

客户端的端口:3787

客户端的信息:我是徐越2

三、多线程服务器

在实际应用中是在服务器上运行一个永久的程序,接收来自其他多个客户端的请求,提供相应的服务。需要利用多线程实现多客户机制。服务器在指定的端口上监听是否有客户请求,一旦监听到就会启动一个专门的服务线程来响应该请求,而服务器本身在启动完线程之后马上又进入监听状态,等待下一个客户的到来。只要将服务端为如下代码,Client1和Client2就会异步执行。

/**

* 多线程服务端0

*

* @author 徐越

*

*/

publicclassMultiThreadServer0

{

// 端口号

privateintport =8821;

// 服务端

privateServerSocket serverSocket;

publicMultiThreadServer0()throwsIOException

{

// 创建服务器端

serverSocket =newServerSocket(port);

System.out.println("服务器启动");

}

publicvoidservice()

{

while(true)

{

Socket socket =null;

try

{

// 客户端进行连接时会触发accept方法从而建立连接

socket = serverSocket.accept();

newMultiThreadHandler(socket).start();

}

catch(Exception e)

{

e.printStackTrace();

}

}

}

publicstaticvoidmain(String[] args)throwsIOException

{

newMultiThreadServer1().service();

}

}

/**

* 多线程处理类

*/

classMultiThreadHandlerextendsThread

{

privateSocket socket;

publicMultiThreadHandler(Socket socket)

{

this.socket = socket;

}

privateBufferedReader getReader(Socket socket)throwsIOException

{

InputStream socketIn = socket.getInputStream();

// InputStreamReader为转换流

// InputStream本是字节流,现加一个Reader,表示用字符流的方式读取字节流

InputStreamReader isr =newInputStreamReader(socketIn);

returnnewBufferedReader(isr);

}

publicvoidrun()

{

try

{

BufferedReader br = getReader(socket);

String msg =null;

while((msg = br.readLine()) !=null)

{

System.out.println("客户端的IP:"+ socket.getInetAddress().getHostAddress());

System.out.println("客户端的端口:"+ socket.getPort());

System.out.println("客户端的信息:"+ msg);

}

}

catch(IOException e)

{

e.printStackTrace();

}

finally

{

try

{

if(socket !=null)

{

socket.close();

}

}

catch(IOException e)

{

e.printStackTrace();

}

}

}

}

/**

* 多线程服务端1

*/

publicclassMultiThreadServer1

{

// 端口号

privateintport =8821;

// 服务端

privateServerSocket serverSocket;

// 线程池

privateExecutorService executorService;

// 单个CPU线程池大小

privatefinalintPOOL_SIZE =10;

publicMultiThreadServer1()throwsIOException

{

// 创建服务器端

serverSocket =newServerSocket(port);

// 获取当前系统的CPU数目

intcpuNums = Runtime.getRuntime().availableProcessors();

// 根据系统资源情况灵活定义线程池大小

executorService = Executors.newFixedThreadPool(cpuNums * POOL_SIZE);

System.out.println("服务器启动");

}

publicvoidservice()

{

while(true)

{

Socket socket =null;

try

{

// 客户进行连接就会触发accept方法从而建立连接

socket = serverSocket.accept();

// 调用线程池操作

executorService.execute(newHandler(socket));

}

catch(Exception e)

{

e.printStackTrace();

}

}

}

publicstaticvoidmain(String[] args)throwsIOException

{

newMultiThreadServer1().service();

}

}

/**

* 多线程处理类

*/

classHandlerimplementsRunnable

{

privateSocket socket;

publicHandler(Socket socket)

{

this.socket = socket;

}

privateBufferedReader getReader(Socket socket)throwsIOException

{

InputStream socketIn = socket.getInputStream();

// InputStreamReader为转换流

// InputStream本是字节流,现加一个Reader,表示用字符流的方式读取字节流

InputStreamReader isr =newInputStreamReader(socketIn);

returnnewBufferedReader(isr);

}

publicvoidrun()

{

try

{

BufferedReader br = getReader(socket);

String msg =null;

while((msg = br.readLine()) !=null)

{

System.out.println("客户端的IP:"+ socket.getInetAddress().getHostAddress());

System.out.println("客户端的端口:"+ socket.getPort());

System.out.println("客户端的信息:"+ msg);

}

}

catch(IOException e)

{

e.printStackTrace();

}

finally

{

try

{

if(socket !=null)

{

socket.close();

}

}

catch(IOException e)

{

e.printStackTrace();

}

}

}

}

两个多线程服务端执行结果相同

服务器启动

客户端的IP:127.0.0.1

客户端的端口:3931

客户端的信息:我是徐越2

客户端的IP:127.0.0.1

客户端的端口:3928

客户端的信息:我是徐越1

参考地址:http://www.2cto.com/kf/201209/158518.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值