Java网络编程之TCP网络通信

1      网络编程----TCPNo24

public class Server {

public static void main(String[] args){

try {

ServerSocket ss =new ServerSocket(8888);//在8888端口上建立ServerSocket

Socket s =ss.accept();//监听客户端的连接请求,一旦连接请求到达,建立连接,会返回一个服务器端的Socket

InputStream is =s.getInputStream();//获取这个Socket的输入流,用于读取客户端传来的信息

int b = is.read();//读一个字节

System.out.println(b);//打印

s.close();//关闭和客户端的连接

ss.close();//关闭ServerSocket,之后不再去监听端的连接请求

} catch (IOException e) {

// TODOAuto-generated catch block

e.printStackTrace();

}

}

}

public class Client {

public static void main(String[] args){

try {

Socket s = newSocket("127.0.0.1",8881);//向本机8888端口发送连接请求

OutputStream os =s.getOutputStream();//获取客户端Socket的输出流

os.write(100);//写一个字节100

s.close();//关闭套接字

} catch (IOException e) {

// TODOAuto-generated catch block

e.printStackTrace();

}

}

}

网络

Protocol协议就是一种格式、约定,网络两端的主机可以根据这个约定来进行信息的交互和传输

网络四层协议体系架构TCP/IP

1、应用层  http、ftp

2、传输层  TCP、UDP

3、网络互联层  IP

4、主机到网络层

1.1    基本网络知识

1.1.1  Ip地址

InetAddress类的使用:

getByName(Stringhost):根据主机名获取IP对象

getHostAddress():获取主机地址

getHostName():获取主机名

getAllByName(Stringhost):获取主机名获取所有的IP对象

getLocalHost():获取本地主机对应的IP地址(127.0.0.1)

示例代码

//在Java中,使用InetAddress类描叙网络地址

InetAddress inetAddr = null;

//创建InetAddress对象

//在互联网上访问服务器有两种形式:1、ip地址   2、主机名(例如:http://www.baidu.com)

//               inetAddr =InetAddress.getByName("www.baidu.com");

//               inetAddr =InetAddress.getByName("192.168.35.1");

//               inetAddr =InetAddress.getByName("192.168.81.144");

//               inetAddr = InetAddress.getByName("localhost");

//获取本机ip地址

inetAddr =InetAddress.getLocalHost();

//ip地址

String address =inetAddr.getHostAddress();

//主机名

String host =inetAddr.getHostName();

System.out.println(address+":"+host);

InetAddress[] inetAddresses=InetAddress.getAllByName("www.baidu.com");

for (InetAddress inet :inetAddresses) {

System.out.println(inet.getHostAddress());

}

1.1.2  网络编程三要素

IP地址:网络中每台主机都必须有一个唯一的IP地址(网络中设备的标识)

端口:用于标识进程的逻辑地址,每个进程都有各自不同的标识, 有效端口0~65535,其中0-1024系统使用或保留端口

传输协议UDP---《将数据、源地址和目的地址封装在数据报包中;每个数据报的大小被限制在64K以内;不需要建立连接;是不可靠协议,速度快》

TCP----《建立连接,形成传输数据的通道;在连接中进行大数据传输;通过三次握手完成连接;必须建立连接;是可靠协议,效率较低》

通过三次握手完成连接:

【1. 客户端向服务器发送包含初始序列值的数据段,开启通信会话

2.      服务器发送包含确认值的数据段,其值等于收到的序列值加1,并加上其自身的同步序列值

3.      发送带确认值的客户端响应,其值等于接受的序列值加1.这便完成了整个建立连接的过程】

1.1.3  Socket(套接字)

1、Socket是为了网络服务而提供的一种机制;

2、套接字是两台机器间通信的端点;

3、网络通信其实就是Socket间的通信(所以网络编程又称为Socket编程);

4、Socket之间通过IO流来进行数据的传输(TCP);

5、Socket = IP地址 + 端口

TCP  Transmit Control Protocol传输控制协议

可以将IP报文进行包装、组织,有序可靠地传输到网络另一端

是基于连接的,两个主机在进行通信前必须先建立连接(三次握手)

(UDPUser Datagram protocol用户数据报协议,不需要连接,信息传输会发生丢失)

协议都是跨语言、跨平台的

1.2    Java实现Tcp通信

如何用Java来进行TCP通信:

ServerSocket服务器套接字,用来监听客户端发送来的连接请求,一旦有客户端请求连接,就可以生成一个连接,并获取服务端这头的Socket

构造方法:ServerSocket(int port)在端口port上建立服务端套接字

Socketaccept()监听客户端过来的连接请求,是一个阻塞方法,连接请求过来了,它就会返回建立的连接的服务端这头的套接字,这个套接字可以用来向客户端写或者从客户端读信息

Socket套接字,就是网络上两台主机之间建立的连接的两个端点,可以通过它写信息,也可以读信息(套接字可以用于两台连接的主机之间进行通信,读写信息。)

1.2.1  服务端

一:服务端

getOutputStream()获取套接字输出流

write系列方法,使用和文件IO中差不多

getInputStream()获取套接字输入流

read系列方法

1.3    客户端

二:客户端

构造方法:Socket(String address,int port)参数为服务端的地址以及端口号,这样构建时就能发送一个连接请求到服务端,接下来这个创建出来的Socket对象就能用来和服务端通信

getOutputStream()获取套接字输出流

write系列方法,使用和文件IO中差不多

getInputStream()获取套接字输入流

read系列方法

getPort()获取端口号

getInetAddress()获取英特网地址对象(可以调用这个对象的getHostAddress()获取地址字符串)

另有一个4参构造方法Socket(String address,int port,InetAddress addr,int p)可以用第四个参数指定客户端的端口(2参构造方法的客户端端口随机分配)

1.4    实现及理论

Socket类:此类实现客户端套接字

ServerSocket:《此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。

PS:在创建Socket对象时,底层会自动创建一个客户端与服务端之间的通道,这个通道就是Socket流(网络IO流),Socket流既包含输入流,又包含输出流。》

使用步骤:

客户端:【《

1、 创建套接字对象(需要绑定指定的服务器ip地址和端口)

2、 通过IO流和服务端传输数据

3、 关闭Socket,释放资源》

服务端:【《

1、 创建服务端套接字对象(需要绑定端口,以便客户端连接)

2、 等待接收来自客户端的连接请求

3、 通过IO流与客户端传输数据

4、 关闭资源》

代码:

Client.java客户端

publicclassClient {

publicstaticvoidmain(String[]args)throwsUnknownHostException, IOException {

//tcp的客户端

System.out.println("tcp客户端开启...");

/*

*创建Socket对象,当执行这行代码的时候底层会自动和服务端建立连接(三次握手)

*如果连接建立不成功,就会抛出异常

*/

//Socket socket = newSocket("127.0.0.1", 9999);

Socketsocket=newSocket("192.168.81.143", 9999);

//获取IO流对象,通过IO流对象可以实现与服务端的数据传输

// socket.getInputStream();

OutputStreamos=socket.getOutputStream();

os.write("来自tcp客户端的数据".getBytes());

//释放资源,断开与服务端的连接

socket.close();

System.out.println("tcp客户端关闭...");

}

}

服务端:Server.java

publicclass Server {

public static void main(String[] args)throws IOException {

// tcp的服务端

System.out.println("tcp服务端开启...");

// 创建服务端的套接字对象,用于响应来自客户端的连接请求

ServerSocket serverSocket =new ServerSocket(9999);

// 等待接收来自客户端的连接请求,连接成功后会返回与客户端对应的Socket对象

Socket socket =serverSocket.accept(); // 阻塞式方法

// 获取客户端的ip地址

String ip =socket.getInetAddress().getHostAddress();

System.out.println("与" + ip + "建立连接");

InputStream is =socket.getInputStream();

// socket.getOutputStream();

byte[] buf = new byte[1024];

int length = is.read(buf);

System.out.println(ip +":" + new String(buf, 0, length));

// socket.close();

// 释放资源,关闭服务端的套接字,会断开所有的客户端连接

serverSocket.close();

System.out.println("tcp服务端关闭");

}

}

1.5    不间断发送消息到服务器

publicclass Client {

public static void main(String[] args)throws UnknownHostException,

IOException {

// tcp的客户端

System.out.println("tcp客户端开启...");

Socket socket = newSocket("192.168.81.143", 9999);

Scanner scanner = newScanner(System.in);

/*BufferedReader br = newBufferedReader(new InputStreamReader(

socket.getInputStream()));*/

BufferedWriter bw = newBufferedWriter(new OutputStreamWriter(

socket.getOutputStream()));

for(;;){

String line =scanner.nextLine();

bw.write(line);

bw.newLine();

bw.flush();

}

//               socket.close();

//               System.out.println("tcp客户端关闭...");

}

}

publicclass Server {

public static void main(String[] args)throws IOException {

// TODO Auto-generated methodstub

// tcp服务端

System.out.println("TCP服务端开启.....");

ServerSocket serverSocket =new ServerSocket(9999);

Socket socket =serverSocket.accept(); // 阻塞式方法

String ip =socket.getInetAddress().getHostAddress();

System.out.println("与" + ip + "建立连接");

BufferedReader br = newBufferedReader(new InputStreamReader(

socket.getInputStream()));

String line = null;

while((line =br.readLine())!=null){

System.out.println(ip+"发送来:"+line);

}

serverSocket.close();

System.out.println("TCP服务端关闭.....");

}

}

1.6    TCP上传文件到服务器

publicclass Client {

// TCP的客户端

public static void main(String[] args)throws UnknownHostException,

IOException {

// TODO Auto-generated methodstub

System.out.println("TCP客户端开启.......");

Socket socket = newSocket("192.168.81.143", 9999);

// 将指定的文件上传到服务器

// 一边读取文件数据,一边向服务器端写出数据

BufferedInputStream bis = newBufferedInputStream(new FileInputStream(

"g:\\extras下文件.rar"));

BufferedOutputStream bos =new BufferedOutputStream(socket.getOutputStream());

int b=0;

while((b=bis.read())!=-1){

bos.write(b);

}

bos.close();

bis.close();

socket.close();

System.out.println("TCP客户端关闭.......");

}

}

publicclass Server {

public static void main(String[] args)throws IOException {

// TODO Auto-generated methodstub

System.out.println("tcp服务端开启....");

ServerSocket serverSocket =new ServerSocket(9999);

Socket socket =serverSocket.accept();

String clientName =socket.getInetAddress().getHostName();

BufferedInputStream bis = newBufferedInputStream(

socket.getInputStream());

BufferedOutputStream bos =new BufferedOutputStream(

newFileOutputStream("g:\\" + clientName + ".rar"));

int b = 0;

while((b =bis.read()) !=-1){

bos.write(b);

}

bos.close();

bis.close();

System.out.println("tcp服务端关闭...");

}

}

1.7    多用户连接与数据发送

publicclass Client {

public static void main(String[] args)throws UnknownHostException,

IOException {

// TODO Auto-generated methodstub

System.out.println("客户端开启./...");

Socket socket = newSocket("192.168.81.144", 6001);

System.out.println("成功与服务器建立连接....");

// 将键盘录入的数据传输到服务器

BufferedReader br = newBufferedReader(new InputStreamReader(System.in));

BufferedWriter bw = newBufferedWriter(new OutputStreamWriter(

socket.getOutputStream()));

//读一行写一行

String line = null;   //接收从键盘录入的数据

while((line=br.readLine())!=null){

bw.write(line);

bw.newLine();

bw.flush();

}

bw.close();

br.close();

socket.close();

System.out.println("客户端关闭.....");

}

}

//客户端响应线程

publicclass ClientEchoThread extends Thread {

//客户端对应的Socket对象(每个客户端都有自己所对应的Socket对象)

private Socket socket;

private String ip;

public ClientEchoThread(Socket socket){

this.socket = socket;

ip =socket.getInetAddress().getHostAddress();

}

//在线程中执行客户端的响应

@Override

public void run() {

System.out.println("建立与"+ip+"的连接");

BufferedReader br =null;

try {

br =newBufferedReader(new InputStreamReader(socket.getInputStream()));

//读取来自客户端的数据

String line = null;

while((line =br.readLine())!= null){

System.out.println(ip+":"+line);

}

} catch (IOException e) {

// TODOAuto-generated catch block

e.printStackTrace();

}finally{

if(br != null){

try {

br.close();

br= null;

} catch(IOException e) {

//TODO Auto-generated catch block

e.printStackTrace();

}

}

if(socket != null){

try {

socket.close();

socket= null;

} catch(IOException e) {

//TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

}

/**

*开启几个线程?

*     有几个客户端就有几个线程

*什么时候开线程?

*     一旦有了新的客户端,就需要开启一个新的线程

*线程中应该包含哪些代码?

*     响应客户端的请求

*/

publicclass Server {

public static void main(String[] args)throws IOException {

// TODO Auto-generated methodstub

System.out.println("服务端开启....");

ServerSocket serverSocket = new ServerSocket(6001);

//接收来自客户端的连接请求

//阻塞式方法,一旦有新的客户端连接,就会返回一个客户端对应的Socket对象

//作为客户端,应该不停地去接受客户端的请求

while(true){

Socket socket =serverSocket.accept();

newClientEchoThread(socket).start();

}

//        serverSocket.close();

//        System.out.println("服务端关闭....");

}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,290评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,107评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,872评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,415评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,453评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,784评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,927评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,691评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,137评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,472评论 2 326
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,622评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,289评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,887评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,316评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,490评论 2 348

推荐阅读更多精彩内容