您的位置:首页 > 编程语言 > Java开发

java socket 多线程的服务端与客户端的demo

2016-07-20 16:51 429 查看
java socket 多线程的服务端与客户端的demo

Socket实现服务器与客户端之间的物理连接,并进行数据传输。主要有TCP/UDP两个协议。Socket处于网络协议的传输层。

TCP:传输控制协议,面向连接的的协议,稳定可靠。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。

UDP:广播式数据传输,UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

优点:1.传输数据为字节级,传输数据可自定义,数据量小。相应的移动端开发,手机费用低

2.传输数据时间短,性能高

3.适合C/S之间信息实时交互

4.可以加密,数据安全性高

缺点: 1.需要对传输的数据进行解析,转化为应用级的数据

2.对开发人员的开发水平要求高

3.相对于Http协议传输,增加了开发量

Http请求主要有http协议,基于http协议的soap协议,常见的http数据请求方式有get和post,web服务

优点:1.基于应用级的接口使用方便

2.要求的开发水平不高,容错性强

缺点: 1.传输速度慢,数据包大。

2.如实现实时交互,服务器性能压力大

3.数据传输安全性差

Socket适用场景:网络游戏,银行交互,支付。

http适用场景:公司OA服务,互联网服务。

1、客户端 模仿发送字节到服务端,建立连接,获取服务端的数据,这时候请注意是长连接,在服务端未收到挂断请求时 连接一直存在, 除非有超时或者网络断开服务端会断开之外,不然连接一直存在。

package cn.okline;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class MyClient
{

public static void main(String[] args)
{
try
{
Socket client = new Socket("localhost", 6666);
MyClient me = new MyClient();
new Thread(me.new Handler(client)).start();
} catch (IOException e)
{
e.printStackTrace();
}
}

class Handler implements Runnable
{
private BufferedReader br;
private DataOutputStream dos;
private DataInputStream dis;
private Socket socket;
private boolean flag = true; // 用于控制循环结束

public Handler(Socket s) throws IOException
{
this.br = new BufferedReader(new InputStreamReader(System.in)); // 用于从控制台接受输入的信息,再发送到服务器
this.socket = s;
this.dos = new DataOutputStream(this.socket.getOutputStream()); // 向服务器写数据的输出流
this.dis = new DataInputStream(this.socket.getInputStream()); // 获取服务器返回数据的输入流
}

@Override
public void run()
{
while (flag)
{
try
{
String str = br.readLine();
if ("exit".equals(str))
{ // 客户端终止发送信息标记 exit
this.br.close();
this.dos.writeUTF(str);
this.dos.flush();

String res = dis.readUTF();
System.out.println(res);

this.dis.close();
this.dos.close();
this.flag = false;
} else
{
this.dos.writeUTF(str);// 每读一行就发送一行
this.dos.flush();
}

} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
}


2、服务端【多线程】,可以同时处理多个客户端请求,此服务端处理接受数据、发送数据到客户端、中间可以处理自己的逻辑程式。如果service端 收到挂断请求,此时连接才会挂断。

package cn.okline;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MyServer {
private ServerSocket serverSocket; //
private ExecutorService servicePool; // 线程池

public MyServer(int port) {
try {
this.serverSocket = new ServerSocket(port);
this.servicePool = Executors.newFixedThreadPool(5);
} catch (IOException e) {
e.printStackTrace();
}
}

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

public void service() {
int i = 0;
while (true) {
try {
Socket socket = this.serverSocket.accept(); // 接受到一个连接,并且返回一个客户端的Socket对象实例
this.servicePool.execute(new Handler(socket));
System.out
.println("User " + i + " is connecting to the Server");
i++;
} catch (IOException e) {
e.printStackTrace();
this.servicePool.shutdown();
}
}
}

class Handler implements Runnable {
private Socket socket;

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

@Override
public void run() {
try {
// 一个输入流,用于获取客户端传来的内容
DataInputStream dis = new DataInputStream(
this.socket.getInputStream());
// 用于产生服务器准备响应的内容
DataOutputStream dos = new DataOutputStream(this.socket.getOutputStream());
String str;
while (null != (str = dis.readUTF())) {
System.out.println(str);
if ("exit".equals(str)) {
System.out.println("客户端发出中断请求");
dos.writeUTF("服务器已经关闭本次连接.");
dos.flush();
//                      dos.writeUTF("exit"); //
//                      dos.flush();

dos.close();
dis.close();
break;
}
}

} catch (IOException e) {
e.printStackTrace();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: