Android Socket编程基础
前些天写了一个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编程基础的更多相关文章
- Android Socket编程
花了大概两天的时间,终于把Android的Socket编程给整明白了.抽空和大家分享一下: Socket Programming on Android Socket 编程基础知识: 主要分服务器端编程 ...
- socket编程基础-字节序/IP/PORT转换/域名
socket编程基础 网络IP操作函数 字符串的IP和32位的IP转换 #include <sys/socket.h> #inlcude <netinet/in.h> #inc ...
- Android 网络编程基础之简单聊天程序
前一篇讲了Android的网络编程基础,今天写了一个简单的聊天程序分享一下 首先是服务端代码: package com.jiao.socketdemo; import java.io.Buffered ...
- c#socket编程基础
Microsoft.Net Framework为应用程序访问Internet提供了分层的.可扩展的以及受管辖的网络服务,其名字空间System.Net和System.Net.Sockets包含丰富的类 ...
- Java从零开始学四十五(Socket编程基础)
一.网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...
- Android网络编程基础
Android网络编程只TCP通信 TCP 服务器端工作的主要步骤如下.步骤1 调用ServerSocket(int port)创建一个ServerSocket,并绑定到指定端口上.步骤2 调用acc ...
- java socket编程基础(转)
一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...
- Android Socket编程学习笔记
http://blog.csdn.net/eyu8874521/article/details/8847173 度娘给出的描述:通常也称作"套接字",用于描述IP地址和端口,是一个 ...
- Python学习笔记——基础篇【第七周】———FTP作业(面向对象编程进阶 & Socket编程基础)
FTP作业 本节内容: 面向对象高级语法部分 Socket开发基础 作业:开发一个支持多用户在线的FTP程序 面向对象高级语法部分 参考:http://www.cnblogs.com/wupeiqi/ ...
随机推荐
- 在ADS上由于volatile惹得祸
C语言关键字volatile是一个危险的东东,笔者再用ADS做S3C2440定时器中断实验就因为这个关键字出了错.出现错误情况的准确描述是:定义一个变量时没有用volatile关键字,而且紧接着whi ...
- Windows Xp Home Edition 安装IIS组件
问题描述: 在虚拟机(操作系统是Windows Xp Home Edition)中安装Sql Server 2005的时候警告缺少IIS相关组件,控制面板"添加/删除组件"中也没有 ...
- Docker日志自动化: ElasticSearch、Logstash、Kibana以及Logspout
http://www.open-open.com/lib/view/open1432107136989.html
- PYTHON连MS SQL示例
先要设置WINDOWS的系统DSN的.然后才可以哟. import pyodbc conxn = pyodbc.connect('DSN=BBB; DATABASE=Northwind;UID=AAA ...
- 【BZOJ 2820】 YY的GCD (莫比乌斯+分块)
YY的GCD Description 神犇YY虐完数论后给傻×kAc出了一题 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少 ...
- mysql日志的查看与开启
mysql的日志类型: 错误日志: log-error 查询日志: log 慢查询日志: log-slow-queries 更新日志: log-update 二进制日志: log-bin 开启错误日志 ...
- 【CF】222 Div.1 B Preparing for the Contest
这样类似的题目不少,很多都是一堆优化条件求最优解,这个题的策略就是二分+贪心.对时间二分, 对费用采用贪心. /* 377B */ #include <iostream> #include ...
- ASP.NET中定制自己的委托和事件参数类
本文笔记选自<庖丁解牛:纵向切入ASP.NET 3.5控件和组件开发技术>一书 一般在实际开发中,对于事件不需要传递数据信息时,像上面的KingTextBox控件的事件,在引发事件时传递的 ...
- HDU 5936 Difference 【中途相遇法】(2016年中国大学生程序设计竞赛(杭州))
Difference Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- MySqlCommand, MySqlParameter and "LIKE" with Percent Symbol
//Wrong way MySqlCommand cmd = oldDb.GetSqlStringCommand(CommandType.Text,"SELECT * _ FROM user ...