如何通过Socket通信控制LED,第1张

对于树莓派来说,可以通过ssh和电脑进行互联,所以一般的应用来说,不需要socket通信,只要打开ssh在树莓派上运行写好的Python或者C程序即可。但是,有的project需要多个sensor,如果仅仅通过打开多个ssh来运行不同程序,这样sensor搜集的数据就不直观,因此就需要在PC上建立一个Server来和树莓派通信,从而可以把所有sensor以及其他devices需要的信号都集中显示在一个PC端的程序上。如果会网页编程的话,在树莓派上建立一个WEB服务器应该也很好实现这个功能。如果不会网页编程,那只好使用socket通信了。最简单的开始,也就是通过socket控制LED的亮与熄。

下面是Server端的程序:# TCP-Serverimport socket

# 1 创建 socket 对象

s = socketsocket(socketAF_INET, socketSOCK_STREAM)

# 2 将 socket 绑定到指定地址 (本机地址)address = ('1921681102', 8889)

sbind(address)

# 3 接收连接请求# listen(backlog), The backlog argument specifies the maximum number of queued connections and should be at least 0;

# the maximum value is system-dependent (usually 5), the minimum value is forced to 0

slisten(5)

print 'Waiting for connection'

# 4 等待客户请求一个连接# 调用 accept 方法时,socket 会进入 "waiting" 状态。

# accept方法返回一个含有两个元素的元组 (connection, address)。

# 第一个元素 connection 是新的 socket 对象,服务器必须通过它与客户通信;

# 第二个元素 address 是客户的 Internet 地址。

new_s, addr = saccept()

print 'Got connect from', addr

# 5 处理:服务器和客户端通过 send 和 recv 方法通信

command = ' '

print ('Please enter 1 to turn on the led, 2 to turn off the led,3 to disconnect the communication:')

while True:

command = raw_input()

new_ssend(command)

data = new_srecv(512)

print data if data == 'Communication is disconnected':

break

# 6 传输结束,关闭连接

new_sclose()

sclose()

接下来是Client端程序:

# TCP-Clientimport RPiGPIO as GPIO

import time

import socket

address = ('1921681102', 8889)

s = socketsocket(socketAF_INET, socketSOCK_STREAM)

sconnect(address)

GPIOsetmode(GPIOBCM)

GPIOsetwarnings(False)

GPIOsetup(27, GPIOOUT)

GPIOsetup(17, GPIOOUT)

GPIOoutput(17, False)

GPIOoutput(27, False)

while True:

command = srecv(512)

if command == '1':

GPIOoutput(27, True)

GPIOoutput(17, False)

ssend('Command 1 received by client')

print "Command is ", command

elif command == '2':

GPIOoutput(27, False)

GPIOoutput(17, True)

ssend('Command 2 received by client')

print "Command is ", command

elif command == '3':

ssend('Communication is disconnected')

print "Command is ", command

break

else:

ssend('Please enter 1, 2 or 3')

print "Command is ", commandsclose()

我们只需要在PC上运行Server的程序,在Raspberry Pi上运行Client的程序便可以控制LED的亮与熄了,很简单。

用socket实现进程通信 ,和socket的普通用法一样,只不过服务端IP为127001 而已

下面附上代码示例:

//服务器端代码 进程1

#include <stdioh>

#include <stdlibh>

#include <stringh>

#include <sys/typesh>

#include <netinet/inh>

#include <sys/socketh>

#include <arpa/ineth>

#include <unistdh>

int main(int argc, char argv[])

{

int sock;

//sendto中使用的对方地址

struct sockaddr_in toAddr;

//在recvfrom中使用的对方主机地址

struct sockaddr_in fromAddr;

int recvLen;

unsigned int addrLen;

char recvBuffer[128];

sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);

if(sock < 0)

{

 printf("创建套接字失败了\r\n");

 exit(0);

}

memset(&fromAddr,0,sizeof(fromAddr));

fromAddrsin_family=AF_INET;

fromAddrsin_addrs_addr=htonl(INADDR_ANY);

fromAddrsin_port = htons(4000);

if(bind(sock,(struct sockaddr)&fromAddr,sizeof(fromAddr))<0)

{

 printf("bind() 函数使用失败了\r\n");

 close(sock);

 exit(1);

}

while(1){

addrLen = sizeof(toAddr);

if((recvLen = recvfrom(sock,recvBuffer,128,0,(struct sockaddr)&toAddr,&addrLen))<0)

{

 printf("()recvfrom()函数使用失败了\r\n");

 close(sock);

 exit(1);

}

if(sendto(sock,recvBuffer,recvLen,0,(struct sockaddr)&toAddr,sizeof(toAddr))!=recvLen){

printf("sendto fail\r\n");

close(sock);

exit(0);

}

return 0;

}

} //客户端代码 进程2

#include <stdioh>

#include <stdlibh>

#include <stringh>

#include <sys/typesh>

#include <netinet/inh>

#include <sys/socketh>

#include <arpa/ineth>

#include <unistdh>int main(int argc, char argv[])

{

if(argc < 2)

{

 printf("请输入要传送的内容\r\n");

 exit(0);

}

int sock;

//sendto中使用的对方地址

struct sockaddr_in toAddr;

//在recvfrom中使用的对方主机地址

struct sockaddr_in fromAddr;unsigned int fromLen;

char recvBuffer[128];

sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);if(sock < 0)

{

 printf("创建套接字失败了\r\n");

 exit(1);

}memset(&toAddr,0,sizeof(toAddr));

toAddrsin_family=AF_INET;

toAddrsin_addrs_addr=inet_addr("127001");

toAddrsin_port = htons(4000);if(sendto(sock,argv[1],strlen(argv[1]),0,(struct sockaddr)&toAddr,sizeof(toAddr)) != strlen(argv[1]))

{

 printf("sendto() 函数使用失败了\r\n");

 close(sock);

 exit(1);

}fromLen = sizeof(fromAddr);

if(recvfrom(sock,recvBuffer,128,0,(struct sockaddr)&fromAddr,&fromLen)<0)

{

 printf("()recvfrom()函数使用失败了\r\n");

 close(sock);

 exit(1);

}

printf("recvfrom() result:%s\r\n",recvBuffer);

close(sock);}

当然可以通信,

不论任何平台或系统之间,通信必须满足两个条件,即端口和协议

说白了,就是通信的窗口,和通信内容的格式。

只要封装Socket的时候,客户端和服务端采用相同的协议和端口即可通信。

至于通信内容的一致性就是另一码事了。

使用多线程,下面的代码,简单实现一个多线程的web服务器:

#coding=utf-8

import socket

import threading

from time import sleep

def response(sock, addr):

    print "收到请求"

    data = sockrecv(1024)

    print data

    socksend(html)

    sockclose()

html = '''HTTP/11 200 OK\nContent-Type: text/html\n\r\nHello world!'''

s = socketsocket(socketAF_INET, socketSOCK_STREAM)

sbind(('0000', 80))

slisten(50)

print "正在等待连接……"

while 1:

    sleep(01)

    sock,addr = saccept()

    t = threadingThread(target=response, args=(sock,addr))

    tstart()

第一层:应用层,定义了用于在网络中进行通信和传输数据的接口;(Http协议位于该层)

第二层:表示层,定义不同系统中数据的传输格式,编码和解码规范等;

第三层:会话层,管理用户的会话,控制用户间逻辑连接的建立和中断;

第四层:传输层,管理着网络中端到端的数据传输;(Tcp协议位于该层)

第五层:网络层,定义网络设备间如何传输数据;(IP位于该层)

第六层:链路层,将上面的网络层的数据包封装成数据帧,便于物理层传输;

第七层:物理层,这一层主要就是传输这些二进制数据。

建立起一个 TCP 连接需要经过“ 三次握手 ”:

握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求。

SYN攻击就是利用三次握手的第二次握手时进行的,这时候服务器处于SYN_RECV状态,等待客户端进行确认ACK,SYN会伪造不存在的源IP,就会有大量的链接处于等待或重试发送SYN+ACK包,导致该阶段队列持续增长,进而导致后续正常请求被丢弃。

HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。

HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。

由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”。

要保持客户端程序的在线状态,需要不断地向服务器发起连接请求,通常情况下即使不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。

通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。但在实际网络应用中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致 Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。

而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。

很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给客户端;若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。

相关视频推荐

看完《tcp/ip详解》不能coding的,一次课开启设计tcp/ip协议栈

深入聊聊websocket协议,tcp分包与粘包解决方案

学习地址:C/C++Linux服务器开发/后台架构师零声教育-学习视频教程-腾讯课堂

需要C/C++ Linux服务器架构师学习资料加qun 812855908 获取(资料包括 C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg 等),免费分享

创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。

socket则是对TCP/IP协议的封装和应用(程序员层面上)。也可以说,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。

关于TCP/IP和HTTP协议的关系,网络有一段比较容易理解的介绍:

平时说的最多的socket是什么呢,实际上socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,才能使用TCP/IP协议。

实际上,Socket跟TCP/IP协议没有必然的联系。Socket编程接口在设计的时候,就希望也能适应其他的网络协议。所以说,Socket的出现 只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而形成了一些最基本的函数接口,比如create、 listen、connect、accept、send、read和write等等。

实际上,传输层 TCP 是基于网络层 IP 协议的,而应用层 HTTP 协议又是基于传输层 TCP 协议的,而 Socket 本身不算是协议,就像上面所说,它只是提供了一个针对 TCP 或者 UDP 编程的接口。

总结:

Socket 其实并不是一个协议,而是为了方便使用 TCP/UDP 而抽象出来的一层,是位于应用层和传输控制层之间的一组接口。

当两台主机通信时,必须通过Socket连接,Socket则利用TCP/IP协议建立TCP连接。TCP连接则更依靠于底层的IP协议,IP协议的连接则依赖于链路层等更低层次。

WebSocket就像HTTP一样,是一个典型的应用层协议。

总结:

WebSocket是HTML5规范提出的一种协议。HTML5 Web Sockets规范定义了Web Sockets API,支持页面使用Web Socket协议与远程主机进行全双工的通信。它引入了WebSocket接口并且定义了一个全双工的通信通道,通过一个单一的套接字在Web上进行操作。

HTML5 Web Sockets以最小的开销高效地提供了Web连接。相较于经常需要使用推送实时数据到客户端甚至通过维护两个HTTP连接来模拟全双工连接的旧的轮询或长轮询(Comet)来说,这就极大的减少了不必要的网络流量与延迟。

相同点:

不同点:

联系:

WebSocket连接的过程:

总结:

你可以在每个用户连上服务器端时,都发送一个消息,就是用4个字节表示是用户的ID,并将与用户通信的socket,用一个HashMap存储起来,而不是用LinkList。

后面如果A发送消息给C,就把A的前四个字节(即ID)取出来,在HashMap中找到与C通信的socket,然后把消息通过socket发送出去····

这部分代码应该很容易实现的,Socket通信这东西,理清了思路就很好弄了~~

Socket是网络上运行的两个程序间双向通讯的一端,它既可以接受请求,也可以发送请求,利用它可以较为方便的编写网络上的数据的传递。在java中,有专门的socket类来处理用户的请求和响应。利用SOCKET类的方法,就可以实现两台计算机之间的通讯。这里就介绍一下在JAVA中如何利用socket进行网络编程。 在Java中Socket可以理解为客户端或者服务器端的一个特殊的对象,这个对象有两个关键的方法,一个是getInputStream方法,另一个是getOutputStream方法。getInputStream方法可以得到一个输入流,客户端的Socket对象上的getInputStream方法得到的输入流其实就是从服务器端发回的数据流。GetOutputStream方法得到一个输出流,客户端Socket对象上的getOutputStream方法返回的输出流就是将要发送到服务器端的数据流,(其实是一个缓冲区,暂时存储将要发送过去的数据)。 程序可以对这些数据流根据需要进行进一步的封装。本文的例子就对这些数据流进行了一定的封装(关于封装可以参考Java中流的实现部分)。 一、建立服务器类 Java中有一个专门用来建立Socket服务器的类,名叫ServerSocket,可以用服务器需要使用的端口号作为参数来创建服务器对象。ServerSocket server = new ServerS

感觉这样的提问没有什么意义

建议看看书,查查资料

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » 如何通过Socket通信控制LED

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情