前些天写了一个Android手机在局域网内利用Wifi进行文件传输的Demo,其中用到了Socket编程,故此总结(盗了网友的一些图和文字)。好久好久没来博客园了~~

1.什么是Socket?

socket英文意思是插座,只有插上插座,才会有电流。如果把他用在网络中,只有建立了socket连接,才能传输数据。网络中的进程是通过socket来通信的,socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。

我的理解就是Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)

 2.使用Socket进行网络通信的过程

Socket通讯的过程大概可以简述为

建立Socket连接-->获得输入/输出流-->读/写数据-->关闭输入/输出流-->关闭Socket

 2.1 Socket 建立连接过程

我们知道tcp建立连接要进行“三次握手”,即交换三个分组。大致流程如下:

  • 客户端向服务器发送一个SYN J
  • 服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1
  • 客户端再想服务器发一个确认ACK K+1

示意图如下:

从图中可以看出,当客户端调用connect时,触发了连接请求,向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;

客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手完毕,连接建立。

 2.2 获取Socket文件流进行数据通讯

图例:

服务端:

ServerSocket serverSocket = new ServerSocket(PORT);
Socket client = serverSocket.accept();// accept()方法监听向这个socket的连接并接收连接。它将会阻塞直到连接被建立好。连接建立好后它会返回一个Socket对象。

InputStream inputstream = client.getInputStream();//获取数据输入流

byte [] data=new byte[4096];

inputstream.read(data);//读入数据

客户端:

Socket socket = new Socket();

try {
      socket.bind(null);
      socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);//指定ip和端口 建立连接,参数 host为IP地址,port为端口名

OutputStream stream = socket.getOutputStream(); //获取文件输出流

stream.write(“socket data”); //向Socket 写入数据

} catch (IOException e) {
        Log.e(TAG, e.getMessage());
} finally {
      if (socket != null) {
      if (socket.isConnected()) {
      try {
      socket.close();//关闭socket
      } catch (IOException e) {
      e.printStackTrace();

}
}

3.使用线程实现服务器端与客户端的双向通信

在应用中,数据通讯肯定是有来有回的,那么我们就要结合多线程技术使用Socket 

设计思想是,用两个线程,一个线程专门用于处理服务器端的读,另一个线程专门用于处理服务器端的写。客户端同理。

代码如下,程序共有六个类。

 

服务器端和其输入输出线程:

package com.example.network;

import java.net.ServerSocket;
import java.net.Socket;

public class MainServer
{
public static void main(String[] args) throws Exception
{
ServerSocket serverSocket = new ServerSocket(4000);

while (true)
{
// 一直处于监听状态,这样可以处理多个用户
Socket socket = serverSocket.accept();

// 启动读写线程
new ServerInputThread(socket).start();
new ServerOutputThread(socket).start();

}

}

}

package com.example.network;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class ServerInputThread extends Thread
{
private Socket socket;

public ServerInputThread(Socket socket)
{
super();
this.socket = socket;
}

@Override
public void run()
{
try
{
// 获得输入流
InputStream is = socket.getInputStream();

while (true)
{
byte[] buffer = new byte[1024];

int length = is.read(buffer);

String str = new String(buffer, 0, length);

System.out.println(str);

}

}
catch (IOException e)
{
e.printStackTrace();
}
}

}

package com.example.network;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

public class ServerOutputThread extends Thread
{
private Socket socket;

public ServerOutputThread(Socket socket)
{
super();
this.socket = socket;
}

@Override
public void run()
{
try
{

OutputStream os = socket.getOutputStream();

while (true)
{
BufferedReader reader = new BufferedReader(
new InputStreamReader(System.in));

String line = reader.readLine();

os.write(line.getBytes());
}
}
catch (IOException e)
{
e.printStackTrace();
}

}

}

 

客户端和其输入输出线程(其输入输出线程和服务器端的完全一样):  

package com.example.network;

import java.net.Socket;

public class MainClient
{

public static void main(String[] args) throws Exception
{
Socket socket = new Socket("127.0.0.1", 4000);

new ClientInputThread(socket).start();
new ClientOutputThread(socket).start();

}
}

package com.example.network;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class ClientInputThread extends Thread
{
private Socket socket;

public ClientInputThread(Socket socket)
{
super();
this.socket = socket;
}

@Override
public void run()
{
try
{
// 获得输入流
InputStream is = socket.getInputStream();

while (true)
{
byte[] buffer = new byte[1024];

int length = is.read(buffer);

String str = new String(buffer, 0, length);

System.out.println(str);

}

}
catch (IOException e)
{
e.printStackTrace();
}
}

}

package com.example.network;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

public class ClientOutputThread extends Thread
{
private Socket socket;

public ClientOutputThread(Socket socket)
{
super();
this.socket = socket;
}

@Override
public void run()
{
try
{

OutputStream os = socket.getOutputStream();

while (true)
{
BufferedReader reader = new BufferedReader(
new InputStreamReader(System.in));

String line = reader.readLine();

os.write(line.getBytes());
}
}
catch (IOException e)
{
e.printStackTrace();
}

}

}

 

Android Socket编程基础的更多相关文章

  1. Android Socket编程

    花了大概两天的时间,终于把Android的Socket编程给整明白了.抽空和大家分享一下: Socket Programming on Android Socket 编程基础知识: 主要分服务器端编程 ...

  2. socket编程基础-字节序/IP/PORT转换/域名

    socket编程基础 网络IP操作函数 字符串的IP和32位的IP转换 #include <sys/socket.h> #inlcude <netinet/in.h> #inc ...

  3. Android 网络编程基础之简单聊天程序

    前一篇讲了Android的网络编程基础,今天写了一个简单的聊天程序分享一下 首先是服务端代码: package com.jiao.socketdemo; import java.io.Buffered ...

  4. c#socket编程基础

    Microsoft.Net Framework为应用程序访问Internet提供了分层的.可扩展的以及受管辖的网络服务,其名字空间System.Net和System.Net.Sockets包含丰富的类 ...

  5. Java从零开始学四十五(Socket编程基础)

    一.网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...

  6. Android网络编程基础

    Android网络编程只TCP通信 TCP 服务器端工作的主要步骤如下.步骤1 调用ServerSocket(int port)创建一个ServerSocket,并绑定到指定端口上.步骤2 调用acc ...

  7. java socket编程基础(转)

    一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...

  8. Android Socket编程学习笔记

    http://blog.csdn.net/eyu8874521/article/details/8847173 度娘给出的描述:通常也称作"套接字",用于描述IP地址和端口,是一个 ...

  9. Python学习笔记——基础篇【第七周】———FTP作业(面向对象编程进阶 & Socket编程基础)

    FTP作业 本节内容: 面向对象高级语法部分 Socket开发基础 作业:开发一个支持多用户在线的FTP程序 面向对象高级语法部分 参考:http://www.cnblogs.com/wupeiqi/ ...

随机推荐

  1. C#中Socket编程解决应用程序直接的通信

    using System;using System.Collections.Generic;using System.Linq;using System.Text; using System.Net; ...

  2. Hibernate Session 获取connection

    Hibernate Session 获取connection 由于最近一个项目要用到一条辅助的SQL ,hibernate里面的SQLQuery API 总的SQL语句不能包含 : 冒号, 固放弃Hi ...

  3. Python的startswith和endswith

    做文本处理的时候经常要判断一个文本有没有以一个子串开始,或者结束.Python为此提供了两个函数: S.startswith(prefix[, start[, end]]) -> bool 如果 ...

  4. 李洪强iOS开发Swift篇—03_字符串和数据类型

    李洪强iOS开发Swift篇—03_字符串和数据类型 一.字符串 字符串是String类型的数据,用双引号""包住文字内容  let website = "http:// ...

  5. Button with Hover Effect (Learned from 百度脑图)

    今天想学学PM的技能, 打开了百度脑图的网站, 看到中间那个按键的hover效果蛮好看, 遂学习一下. 效果如下: Demo 其实就是利用:before绘制了半透明白色的遮罩, 平时用transfor ...

  6. Python自然语言处理学习笔记(69)

    http://www.cnblogs.com/yuxc/archive/2012/02/09/2344474.html Chapter8    Analyzing Sentence Structure ...

  7. Three ways to do WCF instance management

    Three ways to do WCF instance management (Per call, Per session, and Single). IntroductionVery often ...

  8. bzoj1231

    看到n<=16不难想到状压dp 我们用二进制表示前x个位置,哪些牛被已经被选过了 这里我们可以通过穷举二进制数的顺序来转移 所以二维就够了 ..] of longint;     f:.. sh ...

  9. 如何实现Azure虚拟网络中点到站VPN的自动重连

     在Windows Azure早期版本中,用户要在某台Azure平台之外的机器与Azure平台内部的机器建立专用连接,可以借助Azure Connect这个功能.当前的Azure版本,已经没有Az ...

  10. java 正则表达式去除标点符号

      public class Test { public static void main(String[] args) { String str = "!!!??!!!!%*)%¥!KTV ...