您的位置:首页 > 理论基础 > 计算机网络

JAVA socket实现TCP/UDP的多线程通信

2017-03-14 21:50 295 查看

TCP

服务端

package com.nicovon.socket;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
* 服务端
*/
public class Server {

public static void main(String[] args) {
try {
//创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
ServerSocket serverSocket = new ServerSocket(8888);
//记录客户端的数量
int count = 0;
System.out.println("服务端已启动,等待客户端发送消息");
//循环监听等待客户端连接
while (true) {
//调用accept方法开始监听,等待客户端连接,进入阻塞状态
Socket socket = serverSocket.accept();
//创建一个新的线程
ServerRunnable runnable = new ServerRunnable(socket);
Thread serverThread = new Thread(runnable);
//启动线程
serverThread.start();

count++;
System.out.println("客户端数量:" + count);
InetAddress address = socket.getInetAddress();
System.out.println("客户端IP:" + address.getHostAddress());
}
} catch (IOException e) {
e.printStackTrace();
}

}
}


服务器线程处理

package com.nicovon.socket;

import java.io.*;
import java.net.Socket;

/**
* 服务器线程处理类
*/
public class ServerRunnable implements Runnable {

//和本线程相关的Socket
private Socket socket = null;

ServerRunnable(Socket socket) {
this.socket = socket;
}

//线程执行的操作,响应客户端请求
public void run() {
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
PrintWriter pw = null;
try {
//获取输入流,并获取客户端信息
is = socket.getInputStream();
//将字节流转换为字符流
isr = new InputStreamReader(is);
//为输入流添加缓冲
br = new BufferedReader(isr);
String info;
while ((info = br.readLine()) != null) {
System.out.println("收到客户端消息:" + info);
}
//关闭输入流
socket.shutdownInput();

//获取输出流,响应客户端的请求
os = socket.getOutputStream();
pw = new PrintWriter(os);//包装为打印流
pw.write("欢迎您");
pw.flush();//将缓冲输出

} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
try {
if (pw != null)
pw.close();
if (os != null)
os.close();
if (br != null)
br.close();
if (isr != null)
isr.close();
if (is != null)
is.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


客户端

package com.nicovon.socket;

import java.io.*;
import java.net.Socket;

/**
* 客户端
*/
public class Client {

public static void main(String[] args) {

try {
//创建客户端Socket,指定服务器地址和端口
Socket socket = new Socket("localhost", 8888);
//获取输出流,用来向服务器端发送信息
OutputStream os = socket.getOutputStream();//字节输出流
//将输出流包装为打印流
PrintWriter pw = new PrintWriter(os);

String sendMsg = "用户名:tom;密码:222";
pw.write(sendMsg);
pw.flush();
System.out.println("向服务端发送消息:" + sendMsg);
socket.shutdownOutput();

//获取输入流,用来读取服务器端的响应
InputStream is = socket.getInputStream();
//将字节流转换为字符流
InputStreamReader isr = new InputStreamReader(is);
//为输入流添加缓冲
BufferedReader br = new BufferedReader(isr);
String info = null;
while ((info = br.readLine()) != null) {
System.out.println("服务器响应消息:" + info);
}
//关闭输入流
socket.shutdownInput();

//关闭资源
br.close();
isr.close();
is.close();
pw.close();
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


UDP

服务端

package com.nicovon.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
* 服务器端实现基于UDP的通信
*/
public class UDPServer {

public static void main(String[] args) throws IOException {
//创建服务器端DatagramSocket,指定端口号
DatagramSocket socket = new DatagramSocket(8800);
System.out.println("UDP服务端已启动,等待客户端消息");
int count = 0;
while (true) {
//创建数据报,用于接受客户端发来的数据
byte[] data = new byte[1024];//创建字节数组,指定接收的数据报大小
DatagramPacket packet = new DatagramPacket(data, data.length);
//接收客户端发送的数据
socket.receive(packet);//在接收到数据之前一直处于阻塞状态
//创建一个新线程
UDPServerRunnable udpServerRunnable = new UDPServerRunnable(socket, data, packet);
Thread udpServerThread = new Thread(udpServerRunnable);
//启动线程
udpServerThread.start();

count++;
System.out.println("客户端数量:" + count);
InetAddress address = packet.getAddress();
System.out.println("客户端IP:" + address.getHostAddress());
}
}
}


服务端线程处理

package com.nicovon.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
* 基于UDP的服务器多线程处理类
*/
public class UDPServerRunnable implements Runnable {

private DatagramSocket socket;
private byte[] data;
private DatagramPacket packet;

UDPServerRunnable(DatagramSocket socket, byte[] data, DatagramPacket packet){
this.socket = socket;
this.data = data;
this.packet = packet;
}

public void run() {
try {
//读取数据
String info = new String(data, 0, packet.getLength());
System.out.println("客户端发来消息:" + info);

/*
* 响应客户端
*/
//获取客户端地址、端口号
InetAddress clientAddress = packet.getAddress();
int clientPort = packet.getPort();
byte[] responseData = "欢迎".getBytes();
//创建数据报,包含响应信息
DatagramPacket responsePacket = new DatagramPacket(responseData, responseData.length, clientAddress, clientPort);
//响应客户端
socket.send(responsePacket);
} catch (IOException e){
e.printStackTrace();
}
}
}


客户端

package com.nicovon.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
* 客户端
*/
public class UDPClient {

public static void main(String[] args) throws IOException {
//定义服务器地址、端口号、数据
InetAddress address = InetAddress.getByName("localhost");
int port = 8800;
byte[] data = "用户名:admin;密码:123".getBytes();
//创建数据报,包含发送的信息
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
//创建socket对象
DatagramSocket socket = new DatagramSocket();
//向服务器端发送数据报
socket.send(packet);

/*
* 接收服务器端响应信息
*/
//创建数据报,用于接收服务器端响应数据
byte[] serverResponse = new byte[1024];
DatagramPacket serverPacket = new DatagramPacket(serverResponse, serverResponse.length);
//接收服务器端响应端数据
socket.receive(serverPacket);
//读取数据
String reply = new String(serverResponse, 0, serverPacket.getLength());
System.out.println("客户端响应:" + reply);
//关闭资源
socket.close();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java socket 多线程