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

Java实现简单的Socket服务器与客户端字符串通讯(适合初学者阅读)

2015-03-24 15:47 836 查看
近段时间,频繁看到很多学生做毕业设计用到了Socket通讯技术,问题非常多,特写一个小例子,希望对马上毕业的同学有所帮助。

如果希望学习的更加深入,需要掌握的知识有:面向对象、多线程、Socket通讯、IO流、异常处理

服务器端代码:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintStream;

import java.net.ServerSocket;

import java.net.Socket;

/**

* Socket通讯服务器端

* @author 米强<如转载请保留作者和出处>

* @blog http://hi.baidu.com/mq612/blog

* @blog http://blog.csdn.net/mq612

*/

public class ServerMain {

public ServerMain() {

try {

// 构造服务器ServerSocket对象,参数为服务器端开放的端口号

ServerSocket ss = new ServerSocket(30102);

System.out.println("服务器准备就绪!");

// 死循环可以使服务器持续处于接收客户端状态

while(true){

// 该方法使程序阻塞,等待客户端的链接,当监听到客户端的链接,创建一个Socket对象与客户端单独会话

Socket s = ss.accept();

// 为了不影响服务器监听其它客户端,这里开启了一个线程,由线程处理与这个客户端的会话

new ServerThread(s).start();

}

} catch (IOException e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

new ServerMain();

}

}

/**

* 服务器端与客户端会话的线程

*/

class ServerThread extends Thread {

private Socket s = null;

private BufferedReader read = null;

private PrintStream print = null;

public ServerThread(Socket s) {

this.s = s;

try {

// 从Socket中获取输入流和输出流,由于我们只做一个简单的字符串通讯,所以采用BufferedRead和PrintStream来封装输入、输出流

read = new BufferedReader(new InputStreamReader(s.getInputStream()));

print = new PrintStream(s.getOutputStream());

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 线程的运行run方法

*/

public void run() {

try {

String message = null;

// 这里循环可以使服务器持续的接收客户端信息。read.readLine()通过输入流读取一段字符串,赋值给message变量,如果message字符串不为“exit”则循环,否则结束循环

while (!(message = read.readLine()).equals("exit")){

// 将字符串前面添加“返回:”,再发回客户端

print.println("返回:" + message);

}

} catch (IOException e) {

} finally {

// 在 finally 代码块中无论如何都会执行下面代码:

try {

// 如果没有关闭Socket

if(!s.isClosed()){

// 关闭Socket链接

s.close();

}

} catch (IOException e1) {

e1.printStackTrace();

}

}

}

}

客户端代码:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintStream;

import java.net.Socket;

import java.net.UnknownHostException;

import java.util.Scanner;

/**

* Socket通讯客户端

* @author 米强<如转载请保留作者和出处>

* @blog http://hi.baidu.com/mq612/blog

* @blog http://blog.csdn.net/mq612

*/

public class ClientMain {

public ClientMain() {

try {

// 构造与服务器通讯的Socket对象,参数为服务器IP地址(String)和端口号(int),端口号需要和服务器端开放的端口号对应

Socket s = new Socket("192.168.1.100", 30102);

// 启动一个线程与服务器通讯,并把链接服务器的Socket对象传递过去

new LinkThread(s).start();

} catch (UnknownHostException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

new ClientMain();

}

}

/**

* 与服务器通讯的线程

*/

class LinkThread extends Thread {

private Socket s = null;

// 输出流

private PrintStream out = null;

// 缓冲输入流

private BufferedReader in = null;

// 录入文字的Scanner对象

private Scanner scanner = null;

public LinkThread(Socket s) {

// 将Socket对象实例保存在全局变量中,因为run方法中我们还要用它断开链接

this.s = s;

try {

// 从Socket中获取输入流和输出流,由于我们只做一个简单的字符串通讯,所以采用BufferedRead和PrintStream来封装输入、输出流

out = new PrintStream(s.getOutputStream());

in = new BufferedReader(new InputStreamReader(s.getInputStream()));

} catch (UnknownHostException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 线程的运行run方法

*/

public void run() {

// 构造Scanner对象

scanner = new Scanner(System.in);

System.out.println("提示:如果要结束本次会话,请输入“exit”指令!");

try {

// 死循环可以使客户端不断的向服务器发送信息,不用担心循环无法结束,后面的return语句可以结束整个线程。

while(true){

// 提示用户输入文字

System.out.print("请输入:");

// 将用户输入的字符串保存在message变量中

String message = scanner.nextLine();

// 通过输出流发送字符串

out.println(message);

// 清空缓冲,强制输出

out.flush();

// 获取服务器返回的字符串

String str = in.readLine();

// 如果返回的字符串存在

if(str != null){

// 显示在控制台

System.out.println(str);

}else{

// 提示会话结束,并结束线程

System.out.println("本次会话结束!");

return;

}

}

} catch (IOException e) {

e.printStackTrace();

} finally {

// 在 finally 代码块中无论如何都会执行下面代码:

try {

// 如果没有关闭Socket

if(!s.isClosed()){

// 关闭Socket链接

s.close();

}

} catch (IOException e1) {

e1.printStackTrace();

}

}

}

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