java套接字通信_JAVA套接字实现简易的双人通信系统

JAVA套接字实现简易的双人通信系统

JAVA套接字资料

socket是基于应用服务与TCP/IP通信之间的一个抽象,他将TCP/IP协议里面复杂的通信逻辑进行分装,对用户来说,只要通过一组简单的API就可以实现网络的连接。借用网络上一组socket通信图给大家进行详细讲解:

8943d06cb36684209983ba6cb259bfa1.png

首先,服务端初始化ServerSocket,然后对指定的端口进行绑定,接着对端口及进行监听,通过调用accept方法阻塞,此时,如果客户端有一个socket连接到服务端,那么服务端通过监听和accept方法可以与客户端进行连接。

以上资料:

解决方案

综上所述,JAVA套接字需要一个SeverSocket对象作为服务端,监听Socket的连接请求,需要一个Socket对象作为客户端,向SeverSocket发送连接的请求。客户端和服务端建立连接后为全双工,两端均可接收和发送数据,接收和发送可以用流来实现。所以用SeverSocket和Socket分别作为两端进行通信。

但是如果两端仅仅用while循环来不停的发送和接收数据会发生阻塞,原因是因为一端只有完成发送操作后,才能开始接收操作,而键盘读取字符串的函数是阻塞的,socket流的读操作也会发生阻塞,所以只有键盘输入并按下回车,程序才会继续执行,另一端也相同。最终造成的结果是两端每次只能说一句话,说完后必须等待,只有接收到对方发来信息后,才可也说下一句。

解决方法就是利用多线程,服务端和客户端都设置两个线程,一个线程专门用来接收信息,一个专门用来发送信息。这样,接收和发送互不影响,消除阻塞。

主要代码块

服务端,接收客户端的连接请求,创建新的线程:

bd8a521923848e150fb30a6a30df87bc.png

客户端,请求连接,并创建新的线程:

7656e940b607767d987cbc9d31023a87.png

接收的线程:不断从输入流读取数据并打印

aa1b4e6daa194f19d067b266127d31d3.png

发送的线程:不断从键盘读取字符串并写入输出流

ffefcde82d0154a03044026cab8902f7.png

客户端和服务端的接收和发送进程基本相同

运行结果

965e36268dd295b5c1a287a690b94a36.png

最终代码

服务端

package com;

import java.io.IOException;

import java.io.*;

import java.net.*;

import java.util.Scanner;

public class Server{

static ServerSocket serverSocket;

public static void main(String[] args) {

try {

serverSocket = new ServerSocket(1515);

while(true) {

Socket accept_client = serverSocket.accept();

new Thread(new ServerIn(accept_client)).start();

new Thread(new ServerOut(accept_client)).start();

}

} catch (IOException e) {

e.printStackTrace();

try {

serverSocket.close();

} catch (IOException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

}

}

}

//接受的线程

class ServerIn implements Runnable{

Socket socket;

ServerIn(Socket socket){

this.socket = socket;

}

@Override

public void run() {

try {

InputStream in = socket.getInputStream();

while(true) {

byte infile[] = new byte[1024];

int size = in.read(infile);

String string = new String(infile,0,size);

if(!string.equals("") && !string.equals("\n")) System.out.println("message from client: "+ string);

}

} catch (IOException e) {

e.printStackTrace();

try {

socket.close();

} catch (IOException e1) {

e1.printStackTrace();

}

}

}

}

//发送的线程

class ServerOut implements Runnable{

Socket socket;

Scanner reader = new Scanner(System.in);

ServerOut(Socket socket){

this.socket = socket;

}

public void run() {

try {

OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());

while(true) {

String string = reader.nextLine();

out.write(string);

out.flush();

}

} catch (IOException e) {

e.printStackTrace();

try {

socket.close();

reader.close();

} catch (IOException e1) {

e1.printStackTrace();

}

}

}

}

客户端

package com;

import java.io.*;

import java.util.*;

import java.net.*;

public class Client{

public static void main(String[] args) {

try {

Socket client = new Socket("127.0.0.1",1515);

new Thread(new ClientIn(client)).start();

new Thread(new ClientOut(client)).start();

} catch (IOException e) {

e.printStackTrace();

}

}

}

//接受的线程

class ClientIn implements Runnable{

Socket socket;

ClientIn(Socket socket){

this.socket = socket;

}

@Override

public void run() {

try {

InputStream in = socket.getInputStream();

while(true) {

byte infile[] = new byte[1024];

int size = in.read(infile);

String string = new String(infile,0,size);

if(!string.equals("") && !string.equals("\n")) System.out.println("message from server: "+ string);

}

} catch (IOException e) {

e.printStackTrace();

try {

socket.close();

} catch (IOException e1) {

e1.printStackTrace();

}

}

}

}

//发送的线程

class ClientOut implements Runnable{

Socket socket;

Scanner reader = new Scanner(System.in);

ClientOut(Socket socket){

this.socket = socket;

}

public void run() {

try {

OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());

while(true) {

String string = reader.nextLine();

out.write(string);

out.flush();

}

} catch (IOException e) {

e.printStackTrace();

try {

socket.close();

reader.close();

} catch (IOException e1) {

e1.printStackTrace();

}

}

}

}

计算1913 李文轩

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值