python 网络 socket
---恢复内容开始---
1.socket
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。
2.socket发展和分类
套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。
基于文件类型的套接字家族
套接字家族的名字:AF_UNIX
AF=Address Familly
unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
基于网络类型的套接字家族
套接字家族的名字:AF_INET
(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)
3.socket工作流程:
#!/usr/bin/python env
# coding:utf-8 # 套接字编程 # 基于套接字编程
'''
类似情形 服务端:
1.买手机 socket()
2.绑定手机卡 bind()
3.开机 listen()
4.等电话 拿到一个电话链接 accept()
5.收信息 recv()
6.发信息 send()
7 断开电话链接 close()
8.关机 客户端:
1.买手机 socket()
2.拨电话 connect()
3.发信息 send()
4.收信息 recv()
5.结束通话 close() '''
# 服务端
import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.bind(("127.0.0.1", 8000))
phone.listen(10) # 链接 地址
conn, addr = phone.accept() msg = conn.recv(1024)
print("客户端发来信息: ", msg.decode("utf-8"))
conn.send(msg.upper()) conn.close()
phone.close()
#!/usr/bin/python env
# coding:utf-8 '''
客户端:
1.买手机 socket()
2.拨电话 connect()
3.发信息 send()
4.收信息 recv()
5.结束通话 close()
'''
import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8000)) phone.send("你好".encode("utf-8"))
data = phone.recv(1024)
print("收服务端信息:", data.decode("utf-8"))
4.三次握手四次挥手
5.数据 :用户态数据 内核态数据 缓冲区
6. 解决socket服务器time_out问题
#加入一条socket配置,重用ip和端口 在bind前加 phone.bind(('127.0.0.1',8080))
socket对象.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
7.基于tcp的套接字实例
A. tcp服务端
#!/usr/bin/python env
# coding:utf-8
from socket import * ip_port = ("127.0.0.1", 8000)
back_log = 10
buffer_size = 1024 tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) # 解决socket服务端 time_out问题
tcp_server.bind(ip_port)
tcp_server.listen(back_log) # while 开启多个链接
while True:
conn, addr = tcp_server.accept() # while 和一个客户端循环通信
while True:
# 解决客户端断开链接抛出的异常
try:
print("双向链接:", conn)
print("客户端地址:", addr) data = conn.recv(buffer_size)
# if not data: break # 有的系统上用此方法解决客户端断开连接抛出的异常
print("客户端发来信息:", data.decode("utf-8"))
conn.send(data.upper())
except Exception as e:
break conn.close() tcp_server.close()
B. tcp客户端
#!/usr/bin/python env
# coding:utf-8 from socket import * ip_port = ("127.0.0.1", 8000)
back_log = 10
buffer_size = 1024 tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port) while True:
msg = input(">>: ")
if not msg: continue # 解决输入空数据问题
tcp_client.send(msg.encode("utf-8"))
data = tcp_client.recv(back_log) print("客户端发来信息:", data.decode("utf-8")) tcp_client.close()
8.基于udp的套接字实例
# recv在自己这端缓冲区为空时,阻塞
# recvfrom在自己这端缓冲区为空时,就收一个空???
# udp套接字服务端
from socket import * ip_port = ("127.0.0.1", 8000)
back_log = 10
buffer_size = 1024 udp_server = socket(AF_INET,SOCK_DGRAM)
udp_server.bind(ip_port) while True:
data,addr = udp_server.recvfrom(buffer_size)
if len(data.decode("utf-8")) == 0:continue
print(data.decode("utf-8")) msg = input(">>: ").strip()
# if not msg: continue
udp_server.sendto(msg.encode("utf-8"),addr) # udp套接字客户端
from socket import * ip_port = ("127.0.0.1", 8000)
back_log = 10
buffer_size = 1024 udp_client = socket(AF_INET,SOCK_DGRAM) while True:
msg = input(">>: ").strip()
if not msg: continue
udp_client.sendto(msg.encode("utf-8"),ip_port) data,addr = udp_client.recvfrom(buffer_size)
# if len(data)== 0:continue
print(data.decode("utf-8"))
9.基于udp socket实现ntp服务
# _*_coding:utf-8_*_
__author__ = 'Linhaifeng'
from socket import *
from time import strftime
# ntp服务端
ip_port = ('127.0.0.1', 9000)
bufsize = 1024 tcp_server = socket(AF_INET, SOCK_DGRAM)
tcp_server.bind(ip_port) while True:
msg, addr = tcp_server.recvfrom(bufsize)
print('===>', msg) if not msg:
time_fmt = '%Y-%m-%d %X'
else:
time_fmt = msg.decode('utf-8')
back_msg = strftime(time_fmt) tcp_server.sendto(back_msg.encode('utf-8'), addr) tcp_server.close() # ntp客户端
#_*_coding:utf-8_*_
__author__ = 'Linhaifeng'
from socket import *
ip_port=('127.0.0.1',9000)
bufsize=1024 tcp_client=socket(AF_INET,SOCK_DGRAM) while True:
msg=input('请输入时间格式(例%Y %m %d)>>: ').strip()
tcp_client.sendto(msg.encode('utf-8'),ip_port) data=tcp_client.recv(bufsize) print(data.decode('utf-8')) tcp_client.close()
10.基于tcp socket实现shell 粘包问题解决
# 服务端
# struct 解决粘包
from socket import *
import subprocess
import struct ip_port = ('127.0.0.1', 800)
back_log = 10
buffer_size = 1024 tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log) while True: # 接受多个客户端连接
conn, addr = tcp_server.accept() # 等待连接中
print("新客户端地址: ", addr) while True: #接受一个客户端连接
try:
cmd = conn.recv(buffer_size)
if not cmd:break # 基于linux系统 处理客户端quit处理
print("收到客户端发来的信息:", cmd) res = subprocess.Popen(cmd.decode('utf-8'),shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE)
err = res.stderr.read()
if err:
cmd_res = err
else:
cmd_res = res.stdout.read() if not cmd_res: # 处理cd .. cmd_res 没有返回值是None
cmd_res = 'ok'.encode('gbk') # 解决粘包 length = len(cmd_res) #求出执行命令结果的数据长度
data_length = struct.pack('i',length)
print(data_length) # 发送下次要发送数据的长度
conn.send(data_length) conn.send(cmd_res)
except Exception as e:
print(e)
break conn.close()
tcp_server.close()
#客户端
# 解决粘包
from socket import *
import struct
from functools import partial ip_port = ('192.168.8.102', 800)
buffer_size = 1024 tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port) while True:
cmd = input("[root@localhost ~]# ".strip())
if not cmd: continue
if cmd == 'quit': break tcp_client.send(cmd.encode('utf-8')) # 解决粘包
length_data = tcp_client.recv(4) # 接受服务器发来的下次将要发送数据的长度 整数的长度是4个字节 是一个元组类型
print(length_data)
length = struct.unpack('i', length_data)[0]
print(length) recv_size = 0
recv_msg = b''
while recv_size < length:
recv_msg += tcp_client.recv(buffer_size)
recv_size = len(recv_msg) print("服务器命令执行的结果: ", recv_msg.decode('utf-8'))
tcp_client.close()
11.iter 和 functools中偏函数 partial
l = ["a", "b", "c", "d"] def func():
return l.pop() # 迭代到"b"结束 抛出异常
l1 = iter(func,"b") print(next(l1))
print(next(l1))
# print(next(l1)) # 偏函数
from functools import partial def add(x,y):
return x + y func = partial(add,100)
print(func(1)) # '''
recv_size = 0
recv_msg = b''
while recv_size < length:
recv_msg += tcp_client.recv(buffer_size)
recv_size = len(recv_msg)
'''
recv_msg = "".join(iter(partial(tcp_client.recv,buffer_size),b''))
参考:http://www.cnblogs.com/linhaifeng/articles/6129246.html
---恢复内容结束---
1.socket
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。
2.socket发展和分类
套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。
基于文件类型的套接字家族
套接字家族的名字:AF_UNIX
AF=Address Familly
unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
基于网络类型的套接字家族
套接字家族的名字:AF_INET
(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)
3.socket工作流程:
#!/usr/bin/python env
# coding:utf-8 # 套接字编程 # 基于套接字编程
'''
类似情形 服务端:
1.买手机 socket()
2.绑定手机卡 bind()
3.开机 listen()
4.等电话 拿到一个电话链接 accept()
5.收信息 recv()
6.发信息 send()
7 断开电话链接 close()
8.关机 客户端:
1.买手机 socket()
2.拨电话 connect()
3.发信息 send()
4.收信息 recv()
5.结束通话 close() '''
# 服务端
import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.bind(("127.0.0.1", 8000))
phone.listen(10) # 链接 地址
conn, addr = phone.accept() msg = conn.recv(1024)
print("客户端发来信息: ", msg.decode("utf-8"))
conn.send(msg.upper()) conn.close()
phone.close()
#!/usr/bin/python env
# coding:utf-8 '''
客户端:
1.买手机 socket()
2.拨电话 connect()
3.发信息 send()
4.收信息 recv()
5.结束通话 close()
'''
import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8000)) phone.send("你好".encode("utf-8"))
data = phone.recv(1024)
print("收服务端信息:", data.decode("utf-8"))
4.三次握手四次挥手
5.数据 :用户态数据 内核态数据 缓冲区
6. 解决socket服务器time_out问题
#加入一条socket配置,重用ip和端口 在bind前加 phone.bind(('127.0.0.1',8080))
socket对象.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
7.基于tcp的套接字实例
A. tcp服务端
#!/usr/bin/python env
# coding:utf-8
from socket import * ip_port = ("127.0.0.1", 8000)
back_log = 10
buffer_size = 1024 tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) # 解决socket服务端 time_out问题
tcp_server.bind(ip_port)
tcp_server.listen(back_log) # while 开启多个链接
while True:
conn, addr = tcp_server.accept() # while 和一个客户端循环通信
while True:
# 解决客户端断开链接抛出的异常
try:
print("双向链接:", conn)
print("客户端地址:", addr) data = conn.recv(buffer_size)
# if not data: break # 有的系统上用此方法解决客户端断开连接抛出的异常
print("客户端发来信息:", data.decode("utf-8"))
conn.send(data.upper())
except Exception as e:
break conn.close() tcp_server.close()
B. tcp客户端
#!/usr/bin/python env
# coding:utf-8 from socket import * ip_port = ("127.0.0.1", 8000)
back_log = 10
buffer_size = 1024 tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port) while True:
msg = input(">>: ")
if not msg: continue # 解决输入空数据问题
tcp_client.send(msg.encode("utf-8"))
data = tcp_client.recv(back_log) print("客户端发来信息:", data.decode("utf-8")) tcp_client.close()
8.基于udp的套接字实例
# recv在自己这端缓冲区为空时,阻塞
# recvfrom在自己这端缓冲区为空时,就收一个空???
# udp套接字服务端
from socket import * ip_port = ("127.0.0.1", 8000)
back_log = 10
buffer_size = 1024 udp_server = socket(AF_INET,SOCK_DGRAM)
udp_server.bind(ip_port) while True:
data,addr = udp_server.recvfrom(buffer_size)
if len(data.decode("utf-8")) == 0:continue
print(data.decode("utf-8")) msg = input(">>: ").strip()
# if not msg: continue
udp_server.sendto(msg.encode("utf-8"),addr) # udp套接字客户端
from socket import * ip_port = ("127.0.0.1", 8000)
back_log = 10
buffer_size = 1024 udp_client = socket(AF_INET,SOCK_DGRAM) while True:
msg = input(">>: ").strip()
if not msg: continue
udp_client.sendto(msg.encode("utf-8"),ip_port) data,addr = udp_client.recvfrom(buffer_size)
# if len(data)== 0:continue
print(data.decode("utf-8"))
9.基于udp socket实现ntp服务
# _*_coding:utf-8_*_
__author__ = 'Linhaifeng'
from socket import *
from time import strftime
# ntp服务端
ip_port = ('127.0.0.1', 9000)
bufsize = 1024 tcp_server = socket(AF_INET, SOCK_DGRAM)
tcp_server.bind(ip_port) while True:
msg, addr = tcp_server.recvfrom(bufsize)
print('===>', msg) if not msg:
time_fmt = '%Y-%m-%d %X'
else:
time_fmt = msg.decode('utf-8')
back_msg = strftime(time_fmt) tcp_server.sendto(back_msg.encode('utf-8'), addr) tcp_server.close() # ntp客户端
#_*_coding:utf-8_*_
__author__ = 'Linhaifeng'
from socket import *
ip_port=('127.0.0.1',9000)
bufsize=1024 tcp_client=socket(AF_INET,SOCK_DGRAM) while True:
msg=input('请输入时间格式(例%Y %m %d)>>: ').strip()
tcp_client.sendto(msg.encode('utf-8'),ip_port) data=tcp_client.recv(bufsize) print(data.decode('utf-8')) tcp_client.close()
10.基于tcp socket实现shell 粘包问题解决
# 服务端
# struct 解决粘包
from socket import *
import subprocess
import struct ip_port = ('127.0.0.1', 800)
back_log = 10
buffer_size = 1024 tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log) while True: # 接受多个客户端连接
conn, addr = tcp_server.accept() # 等待连接中
print("新客户端地址: ", addr) while True: #接受一个客户端连接
try:
cmd = conn.recv(buffer_size)
if not cmd:break # 基于linux系统 处理客户端quit处理
print("收到客户端发来的信息:", cmd) res = subprocess.Popen(cmd.decode('utf-8'),shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE)
err = res.stderr.read()
if err:
cmd_res = err
else:
cmd_res = res.stdout.read() if not cmd_res: # 处理cd .. cmd_res 没有返回值是None
cmd_res = 'ok'.encode('gbk') # 解决粘包 length = len(cmd_res) #求出执行命令结果的数据长度
data_length = struct.pack('i',length)
print(data_length) # 发送下次要发送数据的长度
conn.send(data_length) conn.send(cmd_res)
except Exception as e:
print(e)
break conn.close()
tcp_server.close()
#客户端
# 解决粘包
from socket import *
import struct
from functools import partial ip_port = ('192.168.8.102', 800)
buffer_size = 1024 tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port) while True:
cmd = input("[root@localhost ~]# ".strip())
if not cmd: continue
if cmd == 'quit': break tcp_client.send(cmd.encode('utf-8')) # 解决粘包
length_data = tcp_client.recv(4) # 接受服务器发来的下次将要发送数据的长度 整数的长度是4个字节 是一个元组类型
print(length_data)
length = struct.unpack('i', length_data)[0]
print(length) recv_size = 0
recv_msg = b''
while recv_size < length:
recv_msg += tcp_client.recv(buffer_size)
recv_size = len(recv_msg) print("服务器命令执行的结果: ", recv_msg.decode('utf-8'))
tcp_client.close()
11.iter 和 functools中偏函数 partial
l = ["a", "b", "c", "d"] def func():
return l.pop() # 迭代到"b"结束 抛出异常
l1 = iter(func,"b") print(next(l1))
print(next(l1))
# print(next(l1)) # 偏函数
from functools import partial def add(x,y):
return x + y func = partial(add,100)
print(func(1)) # '''
recv_size = 0
recv_msg = b''
while recv_size < length:
recv_msg += tcp_client.recv(buffer_size)
recv_size = len(recv_msg)
'''
recv_msg = "".join(iter(partial(tcp_client.recv,buffer_size),b''))
12.socket实现类ftp 定制报头
发送时: 先发报头长度 再编码报头内容然后发送 最后发真实内容 接收时: 先手报头长度,用struct取出来 根据取出的长度收取报头内容,然后解码,反序列化 从反序列化的结果中取出待取数据的详细信息,然后去取真实的数据内容
# ftp 服务端
from socket import *
import struct
import os
import pickle
ip_port = ('127.0.0.1', 800)
back_log = 10
buffer_size = 1024 tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log) while True: # 接受多个客户端连接
conn, addr = tcp_server.accept() # 等待连接中
print("新客户端地址: ", addr) while True: #接受一个客户端连接
try: filename = str(conn.recv(1024).decode("utf-8"))
print(filename)
# filename = "a.txt"
filesize = os.stat(filename).st_size # 文件信息包括文件名 文件大小
fileinfo = {
"filename": filename,
"filesize": filesize,
} # 文件信息序列化为文件字节
pack = pickle.dumps(fileinfo)
print(pack) # 文件信息字节长度
file_len = len(pack)
print(file_len) # 文件信息字节长度转换为4个字节流
pack_len = struct.pack("i", file_len)
print(pack_len) conn.send(pack_len) # 发送报文头长度
conn.send(pack) # 发送报文
#发送真实的数据
with open(filename,encoding="utf-8") as f:
# print(f.read().encode("utf-8"))
conn.send(f.read().encode("utf-8")) # 发送数据
f.seek(0)
print(f.read().encode("utf-8")) break except Exception as e:
print(e)
break conn.close()
tcp_server.close() # ftp 客户端
from socket import *
import struct
import pickle ip_port = ('127.0.0.1', 800)
buffer_size = 1024 tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port) while True: get_file = input(">># ").strip()
tcp_client.send(get_file.encode("utf-8")) # 接受端
# 字节流中 报文头长度
pack_len = tcp_client.recv(4) # 接受报文头长度
print(pack_len) # 文件字节长度
file_len = struct.unpack("i", pack_len)[0]
print(file_len) # # 文件字节信息
pack = tcp_client.recv(file_len) # 接受报文头
print(pack)
#
# # 文件信息内容
fileinfo = pickle.loads(pack)
print(fileinfo)
# #
filename = fileinfo["filename"]
filesize = fileinfo["filesize"]
filename = "aa" + str(filename) with open(filename, "ab") as f:
recv_size = 0
recv_file = b''
print(filesize)
while recv_size < filesize:
recv_file += tcp_client.recv(buffer_size) # 接受文件内容
recv_size = len(recv_file)
break
print(recv_file)
f.write(recv_file) break tcp_client.close()
参考:http://www.cnblogs.com/linhaifeng/articles/6129246.html
python 网络 socket的更多相关文章
- Python网络socket学习
Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...
- python网络-Socket之udp编程(24)
一.udp简介 udp --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议. udp不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地. udp在 ...
- python网络socket编程
一.服务端 #!/usr/bin/python # -*- coding: UTF-8 -*- import socket import sys from thread import * HOST = ...
- python网络-Socket之TCP编程(26)
一.TCP简介 1.TCP介绍 TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的.可靠的.基于字节流的传输层通信协议. TC ...
- Day07 - Python 网络编程 Socket
1. Python 网络编程 Python 提供了两个级别访问网络服务: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口 ...
- python:socket网络编程
Socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket, 又称为“套接字”. 模块 import socket 创建套接字 socket.socket( ...
- python 网络编程(Socket)
# from wsgiref.simple_server import make_server## def RunServer(environ,start_response):# start_resp ...
- Python网络编程之socket应用
1 引言 本篇主要对Python下网络编程中用到的socket模块进行初步总结.首先从网络基础理论出发,介绍了TCP协议和UDP协议:然后总结了socket中的常用函数:最后通过实际代码展示基本函数的 ...
- python 网络编程 TCP/IP socket UDP
TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...
随机推荐
- CentOS下搭建DHCP服务
DHCP的原理这里就不多说了,这里直接贴配置加解说 1.安装dhcp yum -y install dhcp-4.1.1-63.P1.el6.centos.x86_64 2.编辑/etc/dhcp/d ...
- 认识CSS中精灵技术(sprite)和滑动门
前端之HTML,CSS(十) 精灵技术与精灵图 精灵技术本质 精灵技术是一种处理网页背景图像的方式,实质是将小的背景图片拼接到一张大的背景图像上.拼接成的大图被称为精灵图.浏览器打开网页时,每一个图片 ...
- Mac 10.12安装虚拟机软件VMware Fusion 12
说明:VMware创建的虚拟机是全平台通用的,如果要在Mac下识别,那么在虚拟机的文件夹后面增加后缀[.vmwarevm] 下载: (链接: https://pan.baidu.com/s/1eSLE ...
- Linus' Law
Given enough eyeballs, all bugs are shallow. ------埃里克 ...
- C# 字符串类型介绍与操作
一.关于字符串操作的方法 System.String类提供了很多工具方法,包括返回字符数据长度,查找当前字符串中的子字符串和转换大小写等方法. 在String类中常用的比较字符串的方法主要有Compa ...
- Linux安装phpMywind
1.安装MySQL http://www.cnblogs.com/wangshuyi/p/6091244.html 2.安装apache.php.及其扩展 yum install -y httpd p ...
- ubuntu手动安装PhantomJS
1.切换到主目录:cd ~2.下载安装包:https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-Linux-x86_64.ta ...
- redis之 集群配置(主从复制)
集群的作用: 集群的方式有二种: 第二种的好处是:master宕机以后可以直接切换到slave1 主从通信的过程 先通过dump导出大块的rdb 然后把aof缓冲过来,然后通过replicationf ...
- 之前为dd写的一个小的demo(robotium)
测试类的编写: package com.m1905.dd.mobile; import com.robotium.solo.By; import com.robotium.solo.Solo; imp ...
- Idea与Eclipse操作代码的快捷方式
1.Idea格式化代码的快捷键:ctrl+alt+L 2.在IDEA中创建了properties文件,发现默认中文不会自动进行unicode转码.如下 在project settings - File ...