1 如何实现网络中的主机相互通信

一定的规则,有两套参考模型

(1)osi参考模型,过于理想化,未能在互联网上推行

osi有七层

(2)tcp/ip参考模型,有四层,各层之间通过不同的网络协议传输数据。

应用层: http协议

传输层:TCP UDP协议

网络层:IP协议

物理+数据链路层:Link协议

(3)截图?

2   通信要素一 定位计算机

(1)IP定位互联网上唯一计算机

(2)端口号定位计算机上的应用

(3)定位IP地址和端口号,java类InetAddress可以创建IP类

要素二 在按照协议传输

传输层有两个重要的协议,TCP/IP协议  UDP协议

TCP协议:三次握手,客户端服务端,可靠,大数据,效率低

(1)使用以前,先建立TCP链接,形成通道

(2)传输前采取三次握手,是可靠的,A给B传输,A先给B发信息,B回复A,A开始传输。

(3)TCP协议通信有两个进程,客户端,服务端

(4)可进行大数据传输

(5)传输完毕,需要释放已将建立的链接,效率低。

UDP协议:

(1)将数据、源地址、目的地址 封装成数据包,不需要建立链接

(2)每个数据包限制在64K以内

(3)不可靠

(4)无需释放资源,速度快

3、SOCKET套接字

(1)socket是两台机器间通信的端点

(2)socket允许把网络链接当成一个流,数据在两个socket之间通过IO传输

(3)主动发起请求的是客户端,等待请求的是服务端

4、(1)例1,客户端发送请求,服务端接收打印到控制台

package com.socket.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException; import org.junit.Test; //客户端给服务端发送信息,服务端输出信息到控制台上
public class TCPTest { //客户端
@Test
public void client(){
//1、创建Socket套接字
Socket socket = null;
//2、获取输出流
OutputStream os = null;
try {
socket = new Socket(InetAddress.getByName("127.0.0.1"),8090);
os = socket.getOutputStream();
//3、向服务端写消息
os.write("I am Client".getBytes());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//4、关闭流,套接字
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(os != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} @Test
public void server(){
Socket socket = null;
InputStream is = null;
ServerSocket ss = null;
try {
//1、创建ServerSocket对象,指定端口号
ss = new ServerSocket(8090); //2、接收socket
socket = ss.accept();
//3、获取输入流
is = socket.getInputStream();
//4、读取
byte[] b = new byte[20];
int len;
while((len = is.read(b)) != -1){
String str = new String(b,0,len);
System.out.print(socket.getInetAddress().getHostAddress()+"says"+str);
}
System.out.println("123");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(socket != null ){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ss != null){
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(is != null){
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} }
}

(2)例2,客户端向务务端发送请求,服务端应答

package com.socket.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException; import org.junit.Test; /*
* 向服务端写消息,服务端收到消息后返回消息
*/
public class TCPTest1 { @Test
public void client(){
Socket socket = null;
OutputStream os = null;
InputStream is = null;
try {
InetAddress inetObj = InetAddress.getByName("127.0.0.1");
socket = new Socket(inetObj,8090);
os = socket.getOutputStream(); os.write(("Hello I am " + inetObj.getHostName()).getBytes());
os.flush();
//注意,这里的os不关闭,服务端对应的is.read()方法就会一直处于阻塞状态,无法往下执行,
//所以我们要告诉服务端的inputstream,我这里不会再写了,服务端的is就不会再等待,
//执行此方法,显示告诉服务器,客户端发送完毕
socket.shutdownOutput();
is = socket.getInputStream();
byte[] b = new byte[20];
int len;
while((len = is.read(b)) != -1){
System.out.println("收到服务状的消息"+new String(b,0,len));
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if( os!= null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( socket!= null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
} if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} } @Test
public void server() {
ServerSocket serverSocket = null;
Socket socket = null; try {
serverSocket = new ServerSocket(8090);
while(true){
socket = serverSocket.accept();
handleSocket(socket);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} public void handleSocket(Socket socket){
InputStream is = null;
OutputStream os = null;
try {
is = socket.getInputStream();
byte[] b = new byte[20];
int len;
StringBuffer sbr = new StringBuffer();
while((len = is.read(b)) != -1){
sbr.append(new String(b,0,len));
}
System.out.println("客户端说:"+sbr.toString());
os = socket.getOutputStream();
os.write(sbr.toString().toUpperCase().getBytes());
} catch (IOException e) {
e.printStackTrace();
}finally{
if(os != null){
try {
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(is != null){
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} }
}

(3)客户端发送文件到服务端,服务端接收完毕后,告诉客户端 ,接收完毕

package com.socket.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException; import org.junit.Test; //客户端发送文件给服务端
public class TcpTest2 { @Test
public void fileClient() {
// 1、创建socket对象
Socket socket = null;
// 2、获取输出流
OutputStream os = null;
// 3、先读,把本地文件读入输入流
FileInputStream fis = null; InputStream is = null;
try {
socket = new Socket(InetAddress.getByName("127.0.0.1"), 8090);
os = socket.getOutputStream();
fis = new FileInputStream(new File("d://env.conf"));
byte[] b = new byte[64];
int len;
while ((len = fis.read(b)) != -1) {
// 4、往外写
os.write(b, 0, len);
}
// 5、告诉服务器写完了
socket.shutdownOutput();
// 6、读取从服务器返回的消息
is = socket.getInputStream();
byte[] b1 = new byte[20];
int len1;
while ((len1 = is.read(b1)) != -1) {
System.out.print(new String(b1, 0, len1));
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } } @Test
public void fileServer() {
ServerSocket ss = null;
try {
ss = new ServerSocket(8090);
while(true){
Socket socket = ss.accept();
handleClient(socket);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(ss != null){
ss.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} } public void handleClient(Socket socket){
//1、获取输入流
InputStream is = null;
//2、创建fileoutputStream对象
FileOutputStream fos = null; OutputStream os = null;
try {
is = socket.getInputStream();
fos = new FileOutputStream(new File("d://env1.conf"));
//3、读取服务器发来的字节
int len;
byte b [] = new byte[64];
while((len = is.read(b)) != -1){
fos.write(b, 0, len);
}
fos.flush();
//4、写文件完毕,获取socket的输出流给客户端返回消息
os = socket.getOutputStream();
os.write("Accepted Over !".getBytes());
os.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{ if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } }
}

5、socket通信原理

客户端,创建出一个socket对象时(创建InetAddress对象时,传入的ip是服务器的ip),服务端也接受到一个socket对象

通过socket可以获取输入流和输出流

,客户端通过socket对象的输出流往服务器端写数据,

服务器端通过socket对象的输入流读数据

服务器服务端的通信,实际是sockey里面IO流的通信。

要注意的是,Inputsream的read方法,和ServetSocket的accept方法是阻塞方法。

6、聊天室的做法

1)客户端发送自己的名字a,消息,送达人的名字b,拼接成一个字符串。

2)服务端,接到a的请求,截取字符串,把a和a对应的socket对象放到map里面,然后启动一个线程,传入b .socket,

3)线程里面,通过b从map里面获取b的socket,获取b的输出流,把a和a说的话写出去

4)客户b的输入流接受到输出流发来的消息,结束。

7、需要注意的事项都写在注释里面,下面放一张时序图,画的不太标准

网络编程1-TCP编程(socket)的更多相关文章

  1. 网络编程之TCP编程

    网络编程之TCP编程 前面已经介绍过关于TCP协议的东西,这里不做赘述.Java对于基于TCP协议的网络通信提供了良好的封装,Java使用socket对象来代表两端的通信窗口,并通过Socket产生I ...

  2. [Python] 网络编程之TCP编程

    转自:TCP编程 - 廖雪峰的官方网站 Socket是网络编程的一个抽象概念.通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协 ...

  3. Linux网络编程系列-TCP编程实例

    实例: client #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #inc ...

  4. JAVA与网络开发(TCP:Socket、ServerSocket;UDP:DatagramSocket、DatagramPacket;多线程的C/S通讯、RMI开发概述)

    通过TCP建立可靠通讯信道 1)为了对应TCP协议里的客户端和服务器端,Socket包提供了Socket类和ServerSocket类. 2)Socket类构造函数及相关方法 Public Socke ...

  5. C#网络程序设计(3)网络传输编程之TCP编程

        网络传输编程指基于各种网络协议进行编程,包括TCP编程,UDP编程,P2P编程.本节介绍TCP编程.     (1)TCP简介: TCP是TCP/IP体系中最重要的传输层协议,它提供全双工和可 ...

  6. 牛客网Java刷题知识点之TCP、UDP、TCP和UDP的区别、socket、TCP编程的客户端一般步骤、TCP编程的服务器端一般步骤、UDP编程的客户端一般步骤、UDP编程的服务器端一般步骤

    福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑         Java全栈大联盟   ...

  7. 第1章 网络编程基础(3)——基本Socket通信

    服务器常用模型

  8. 网络层、传输层、应用层、端口通信协议编程接口 - http,socket,tcp/ip 网络传输与通讯知识总结

    引: http://coach.iteye.com/blog/2024511 什么是TCP和UDP,以及二者区别是什么? TCP的全称为传输控制协议.这种协议可以提供面向连接的.可靠的.点到点的通信. ...

  9. 网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程

    Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服 ...

  10. 网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接

    本文原作者:“水晶虾饺”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.引言 好多小白初次接触即时通讯(比如:IM或者消息推送应用)时,总是不 ...

随机推荐

  1. 【Alpha版本】 第十天 11.18

    一.站立式会议照片: 二.项目燃尽图: 三.项目进展: 成 员 昨天完成任务 今天完成任务 明天要做任务 问题困难 心得体会 胡泽善 完成管理员的三大功能界面框架, 我要招聘查看报名者的列表显示 完成 ...

  2. 《Linux菜鸟入门2》Ldap

    ldap网络帐号1.ldap是什么ldap目录服务认证,和windows活动目录类似,就是记录数据的一种方式 2.ldap客户端所需软件yum install sssd krb-workstation ...

  3. php 读取excel表格中的内容

    <?php /** * excel表格内容在网页中显示 * * 首先需要下载PHPExcel 工具包 * 网址: http://phpexcel.codeplex.com/releases/vi ...

  4. 10月17日下午MySQl数据库CRUD高级查询

    高级查询:1.连接查询 #适用于有外键关系的  没有任何关系没法用select * from Info,Nation #同时查询这俩表并把两表每个数据相互组合,形成笛卡尔积 select * from ...

  5. 9月23日JavaScript作业----子菜单下拉

    例题一.子菜单下拉 <style type="text/css"> *{ margin:0px auto; padding:0px} #menu{ width:700p ...

  6. Java排序算法——插入排序

    import java.util.Arrays; //================================================= // File Name : Select_S ...

  7. css3 中的transition和transform

    我以前始终都把他搞反,或者是混淆.现在可以稍微小结下. Transition:CSS3中处理动画的一个样式:只涉及动画起始和终止两个状态.如果涉及到一个动画的各个时间或者状态,那就必须要用到的另外一个 ...

  8. CentOS 7 AMD64安装nginx和mysql

    NGINX: rpm -ivh http://nginx.org/packages/centos/7/x86_64/RPMS/nginx-1.8.0-1.el7.ngx.x86_64.rpm 查看: ...

  9. ECSHOP MYSQL 公用类库中的autoExecute方法

    include/cls_mysql.php 正常操作 例如: $sql = “UPDATE ecs_user SET user = ‘buxuan’ WHERE user_id = ″; $db-&g ...

  10. Vim以及Terminal 配色方案---"Solarized"配色

    linux用户给vim 以及terminal的配色方案---Solarized配色 官网地址:http://ethanschoonover.com/solarized 看这配色:八卦乾坤,赏心悦目,高 ...