栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java利用TCP协议实现客户端与服务器通信【附通信源码】

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java利用TCP协议实现客户端与服务器通信【附通信源码】

ServerSocket类存在于Java.net包中,表示服务器端的套接字,在使用时需要首先导入这个类,我们也知道ServerSocket类的主要功能就是通过指定的端口等待来自于网络中客户端的请求并且进行连接。

值得注意的是:服务器套接字一次只能与一个客户端套接字进行连接,因此如果存在多台客户端同时发送连接请求,则服务器套接字就会将请求的客户端存放到队列中去,然后从中取出一个套接字与服务器建立的套接字进行连接,但是服务器端能够容纳的客户端套接字也不是无限的,当请求连接的数量大于最大容纳量时,那么多出来的请求就会被拒接,一般来说队列的默认大小是50。

ServerSocket类的构造方法通常会抛出IOException异常,具体有以下几种形式:

  • ServerSocket():创建非绑定服务器套接字

  • ServerSocket(inr port):创建绑定到特定端口的服务器套接字

  • ServerSocket(int port, int backlog):利用指定的backlog创建服务器套接字,并将其绑定到指定的服务器端口上,

  • ServerSocket(int port, int backlog, InetAddress bindAddress):使用指定的端口,侦听backlog和要绑定到本地的IP地址创建服务器。这种情况适用于计算机上有多个网卡和多个IP地址的情况,用户可以明确的规定ServerSocket在哪块网卡或哪个IP地址上等待用户的连接请求。

以下是ServerSocket类中一些常用的方法:

ServerSocket类中常用的方法

方法

返回值说明
accept()Socket等待客户机连接,若连接则创建一个客户端套接字
isBound()boolean判断ServerSocket的绑定状态
getInetAddress()InetAddress返回此服务器套接字的本地地址
isClosed()boolean返回服务器套接字的关闭状态
close()void关闭服务器套接字
bind(SocketAddress endpoint)void将ServerSocket绑定到特定地址(IP地址和端口号)
getInetAddress()int返回服务器套接字等待的端口号

了解了ServerSocket类的基本方法之后,就是如何进行客户端和服务器进行连接的问题了。

在服务器端我们可以调用ServerSocket类的accpet()方法与请求连接的客户机建立连接,这时会返回一个和客户端相连接的Socket对象,这个时候其实已经连接成功了,使用getInetAddress()方法就可以获取到进行请求的客户机的IP地址。

对于如何进行客户端和服务器端数据的通信,就要用到数据的输入流和输出流了,**服务器端的Socket对象使用getOutputStream()方法获取到的输出流,将指向客户端的Socket对象使用getInputStream()方法获取到的输入流。由此就实现在服务器向客户端发送数据的一个过程,**同样的道理,客户端端的Socket对象使用getOutputStream()方法获取到的输出流,将指向服务器端的Socket对象使用getInputStream()方法获取到的输入流。从而实现由客户端向服务器发送数据的过程。

**注意:**accpet()方法会阻塞线程的继续执行,如果在对应的接口没有收到客户端的呼叫,则程序会停留在此处,直到获取到客户端的呼叫才会继续向下执行,但是如果服务器没有收到来自客户端的呼叫请求,并且accpet()方法没有发生阻塞,那么通常情况下就是程序出了问题,一般来说可能是使用了一个已经被其他程序占用了的端口号,导致ServerSocket没有绑定成功!遇到这种情况可以尝试更换新的端口号。

了解了TCP协议的通信过程,接下来就是进行TCP通信程序的书写啦!

在网络通信中,如果只要求客户机向服务器发送信息,不要求服务器向客户端反馈信息的行为称为“单向通信”,要求客户机和服务器双方互相通信的过程称为“双向通信”,双向通信只不过是比单向通信多了一个服务器向客户端发送消息的过程,

接下来分别是服务器端和客户端程序的编写:

服务器端程序

======

package server_1;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

public class MyTcp {

private ServerSocket server; //设置服务器套接字

private Socket client; //设置客户端套接字

//连接客户端函数

void getServer()

{

try {

server = new ServerSocket(1100); //建立服务器 端口为1100

System.out.println(“服务器建立成功!正在等待连接…”);

client = server.accept(); //调用服务器函数对客户端进行连接

System.out.println(“客户端连接成功!ip为:” + client.getInetAddress()); //返回客户端IP

getClientMessage(); //调用信息传输和接收函数

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

void getClientMessage()

{

try {

while (true) {

InputStream is = client.getInputStream(); //获取到客户端的输入流

byte[] b = new byte[1024]; //定义字节数组

int len = is.read(b); //由于信息的传输是以二进制的形式,所以要以二进制的形式进行数据的读取

String data = new String(b, 0,len);

System.out.println(“客户端发来消息:” + data);

//定义发送给客户端的输出流

OutputStream put = client.getOutputStream();

String putText = “我已经收到!欢迎你!”;

put.write(putText.getBytes()); //将输出流信息以二进制的形式进行写入

}

} catch (Exception e) {

// TODO: handle exception

}

try {

//判断客户端字节流不是空,则关闭客户端

if (server != null) {

server.close();

}

} catch (Exception e) {

// TODO: handle exception

}

}

public static void main(String[] args) {

// TODO Auto-generated method stub

MyTcp myTcp = new MyTcp(); //调用该类生成对象

myTcp.getServer(); //调用方法

}

}

客户端程序

=====

package client_1;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.PrintWriter;

import java.net.Socket;

import java.net.UnknownHostException;

public class MyClient {

private Socket client; //定义客户端套接字

//建立客户端函数

void getClient()

{

try {

client = new Socket(“127.0.0.1”, 1100); //建立客户端,使用的IP为127.0.0.1,端口和服务器一样为1100

System.out.println(“客户端建立成功!”);

setClientMessage(); //调用客户端信息写入函数

} catch (UnknownHostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

//定义客户端信息写入函数

void setClientMessage()

{

try {

OutputStream pt = client.getOutputStream(); //建立客户端信息输出流

String printText = “服务器你好!我是客户端!”;

pt.write(printText.getBytes()); //以二进制的形式将信息进行输出

InputStream input = client.getInputStream(); //建立客户端信息输入流

byte [] b = new byte[1024]; //定义字节数组

int len = input.read(b); //读取接收的二进制信息流

String data = new String(b, 0,len);

System.out.println(“收到服务器消息:” + data);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

try {

//如果客户端信息流不为空,则说明客户端已经建立连接,关闭客户端

if (client != null) {

client.close();

}

} catch (Exception e) {

// TODO: handle exception

}

ln(“收到服务器消息:” + data);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

try {

//如果客户端信息流不为空,则说明客户端已经建立连接,关闭客户端

if (client != null) {

client.close();

}

} catch (Exception e) {

// TODO: handle exception

}
[外链图片转存中…(img-Hn4PQhwr-1635177206113)]

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/349464.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号