热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java模拟多线程socket通信

1.socket通信Socket原理机制:1.通信的两端都有Socket2.网络通信其实就是Socket间的通信3.数据在两个Socket间通过IO传输socket和serverSocket通信简单介
1.socket通信

Socket原理机制:
1.通信的两端都有Socket
2.网络通信其实就是Socket间的通信
3.数据在两个Socket间通过IO传输

socket和serverSocket通信简单介绍如下,注意客户端与服务器端是怎么交换数据的:


应用多线程实现服务器与多客户端之间的通信:

① 服务器端创建ServerSocket,循环调用accept()等待客户端连接
② 客户端创建一个socket并请求和服务器端连接
③ 服务器端接受请求,创建socket与该客户建立专线连接
④ 建立连接的两个socket在一个单独的线程上对话
⑤ 服务器端继续等待新的连接

2.服务器端代码

package com.tl.skyLine.socket;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
* 聊天 服务器端
* Created by tl on 17/3/1.
*/
public class ChatServer {
private int port = 8080;// 默认服务器端口

public ChatServer() {
}

// 创建指定端口的服务器
public ChatServer(int port) {
this.port = port;
}

// 提供服务
public void service() {
int i = 0;
try {
// 建立服务器连接,设定客户连接请求队列的长度
ServerSocket server = new ServerSocket(port, 3);
while (true) {
// 等待客户连接
Socket socket = server.accept();
i++;
System.out.println("第" + i + "个客户连接成功!");
new Thread(new ServerThread(socket, i)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
new ChatServer().service();
}
}


class ServerThread implements Runnable {
private int index;
private Socket socket;

public ServerThread(Socket socket, int i) {
this.socket = socket;
this.index = i;
}

// 任务是为一个用户提供服务
@Override
public void run() {
try {
try {
// 读取客户端传过来信息的DataInputStream
DataInputStream in = new DataInputStream(socket
.getInputStream());
// 向客户端发送信息的DataOutputStream
DataOutputStream out = new DataOutputStream(socket
.getOutputStream());
while (true) {
// 读取来自客户端的信息
String accpet = in.readUTF();
System.out.println("第" + index + "个客户端发出消息:" + accpet);
}
} finally {// 建立连接失败的话不会执行socket.close();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

3.客户端代码

package com.tl.skyLine.socket;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Random;
import java.util.Scanner;

/**
* 聊天 客户端
* Created by tl on 17/3/1.
*/
public class ChatClient {
private String host = "localhost";// 默认连接到本机
private int port = 8080;// 默认连接到端口8080

private String name = String.valueOf(new Random().nextInt(999999));//客户端的名字

public ChatClient() {

}

// 连接到指定的主机和端口
public ChatClient(String host, int port) {
this.host = host;
this.port = port;
}

public void chat() {
try {
// 连接到服务器
Socket socket = new Socket(host, port);
// 设置超时
// Socket s = new Socket();
// SocketAddress socketAddress = new InetSocketAddress(serverIp, port);
// s.connect(socketAddress, timeout);
try {
// 读取服务器端传过来信息的DataInputStream
DataInputStream in = new DataInputStream(socket
.getInputStream());
// 向服务器端发送信息的DataOutputStream
DataOutputStream out = new DataOutputStream(socket
.getOutputStream());

// 装饰标准输入流,用于从控制台输入
Scanner scanner = new Scanner(System.in);

while (true) {
String send = scanner.nextLine();
// 把从控制台得到的信息传送给服务器
out.writeUTF("客户端[" + name + "]:" + send);
// 读取来自服务器的信息
String accpet = in.readUTF();
System.out.println(accpet);
}

} finally {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
new ChatClient().chat();
}
}

以上代码利用Socket对象和ServerSocket对象进行简单的网络交互,即客户端通过DataOutputStream对象的writeUTF()方法向服务器发送消息,服务器利用DataInputStream对象的readUTF()方法读出数据。其中ServerSocket对象的accept()方法是阻塞的方法,它会一直等待,直到有客户端连接,同理,DataInputStream对象的readUTF()方法也是阻塞的方法,它也会一直等待,直到客户端调用writeUTF()方法。
上面代码中ChatClient.java中,客户端控制台发送信息之后,String accpet = in.readUTF();将会一直阻塞,如果是单线程的话,重新开一个客户端,也是处于阻塞当中,所以将服务端设置为多线程,这样就不会影响下一个客户端的通信。

4.运行结果:



推荐阅读
author-avatar
手机用户2502862581
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有