当前位置: 澳门新濠3559 > 操作系统 > 正文

然后就可以再程序中使用socket代理来编写程序了

时间:2019-12-08 05:50来源:操作系统
服务器端的程序一般有如下几个过程,首先是bind,然后再是listen,最后是accept。再往后就是客户端与服务器连接后的各种操作了。 服务器端 Python设置Socket代理及实现远程摄像头控制的例

服务器端的程序一般有如下几个过程,首先是bind,然后再是listen,最后是accept。再往后就是客户端与服务器连接后的各种操作了。

服务器端

Python设置Socket代理及实现远程摄像头控制的例子,pythonsocket

为python设置socket代理 首先,你得下载SocksiPy这个.解压出来之后里面会有一个socks.py文件.然后你可以把这个文件复制到python安装目录里面的Libsite-packages中.或者把这个文件复制到程序所在的目录中.
然后就可以再程序中使用socket代理来编写程序了.
下面是示例代码

import socks
import socket
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5,"127.0.0.1",8088)
socket.socket =socks.socksocket
import urllib2
urllib2.urlopen('http://www.baidu.com').read()

通过socket通信实现远程摄像头监控 通过python来实现摄像头监控,然后通过socket通信来将数据发送到远程服务器,这样就可以实现远程监控了.大概找了下资料,果然可以,下面贴出实现过程.
这个程序包括一个服务器和一个客户端。需要的库有 VideoCapture 和 pygame,一个用来得到摄像头的视频,一个用来显示.
服务器端,主要实现监听客户端所发送到指令,如果指令是startCam,则打开摄像头,并向客户端发送数据.

from VideoCapture import Device
import ImageDraw, sys, pygame, time
from pygame.locals import *
import socket
import time
from PIL import ImageEnhance
from threading import Thread
import traceback
import threading





# 全局变量
is_sending = False
cli_address = ('', 0)

# 主机地址和端口
host = 'localhost'
port = 10218

# 初始化UDP socket
ser_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ser_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
ser_socket.bind((host, port))

# 接收线程类,用于接收客户端发送的消息
class UdpReceiver(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)
    self.thread_stop = False

  def run(self):
    while not self.thread_stop:
      # 声明全局变量,接收消息后更改
      global cli_address  
      global is_sending
      try:
        message, address = ser_socket.recvfrom(2048)
      except:
        traceback.print_exc()
        continue
      print message,cli_address
      cli_address = address
      if message == 'startCam':
        print 'start camera',
        is_sending = True
        ser_socket.sendto('startRcv', cli_address)        
      if message == 'quitCam':
        is_sending = False
        print 'quit camera',

  def stop(self):
    self.thread_stop = True


if __name__=='__main__':
  res = (640,480)

  cam = Device()
  cam.setResolution(res[0],res[1])


  brightness = 1.0
  contrast = 1.0
  shots = 0

  receiveThread = UdpReceiver()
  receiveThread.setDaemon(True)      # 该选项设置后使得主线程退出后子线程同时退出
  receiveThread.start()


  while 1:
    if is_sending: 
      camshot = ImageEnhance.Brightness(cam.getImage()).enhance(brightness)
      camshot = ImageEnhance.Contrast(camshot).enhance(contrast)
      clock = pygame.time.Clock()
      img = cam.getImage().resize((160,120))
      data = img.tostring()
      ser_socket.sendto(data, cli_address) 
      time.sleep(0.05) 
    else:
      time.sleep(1)
  receiveThread.stop()
  ser_socket.close()    

客户端:
主要功能是像服务器端发送指令,然后接受服务器所发送过来的数据并通过pygame模块来显示出来.

# -*- coding: UTF-8 -*-

import socket, time
import pygame
from pygame.locals import *
from sys import exit

# 服务器地址,初始化socket
ser_address = ('localhost', 10218)
cli_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 设置超时
cli_socket.settimeout(5)

# 向服务器发送消息,并判断接收时是否超时,若超时则重发
while 1:
  cli_socket.sendto('startCam', ser_address)
  try:
    message, address = cli_socket.recvfrom(2048)
    if message == 'startRcv':
      print message
      break
  except socket.timeout:
    continue

cli_socket.recvfrom(65536)

# 初始化视频窗口
pygame.init()
screen = pygame.display.set_mode((640,480))
pygame.display.set_caption('Web Camera')
pygame.display.flip()

# 设置时间,可以用来控制帧率
clock = pygame.time.Clock()


# 主循环,显示视频信息
while 1:
  try:
    data, address = cli_socket.recvfrom(65536)
  except socket.timeout:
    continue
  camshot = pygame.image.frombuffer(data, (160,120), 'RGB')
  camshot = pygame.transform.scale(camshot, (640, 480))
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      cli_socket.sendto('quitCam', ser_address)
      cli_socket.close()
      pygame.quit()
      exit()
  screen.blit(camshot, (0,0))
  pygame.display.update() 
  clock.tick(20)

客户端就是简单地向服务器发送启动消息,接收到回复后开始进入主循环开始接收视频数据并显示。
由于UDP协议不保证信息是否成功到达,因此前面设置了个重发机制,只有当客户端收到服务器的回复后,才停止发送开启消息并进入主循环.具体见注释.
使用时将localhost改成服务器IP即可.

为python设置socket代理 首先,你得下载SocksiPy这个.解压出来之后里面会有一个soc...

相比之下,客户端的程序就比较简单了,只需先获得sock_id,再与对应的sock进行connect,其他如下。

步骤

  1. 创建一个socket套接字文件描述符
    int serv_然后就可以再程序中使用socket代理来编写程序了.,服务器端代码。sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  2. 创建一个sockaddr_in结构体的变量,并配置相应的参数,然后绑定
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr)); //先清除变量值
    serv_addr.sin_family = AF_INET; //表示使用IPv4地址
    serv_addr.sin_addr.s_澳门新濠3559,addr = inet_addr("127.0.0.1"); //IP地址
    serv_addr.sin_port = htons(1234); //配置通信端口
    bind(serv_sock, (struct sockaddr)serv_addr, sizeof(serv_addr)); //绑定
    知识点:
    a. AF_INET:表示使用IPv4的IP地址,IPv4的IP地址用AF_INET6
    *
    b. inet_addr()函数:将一个点分十进制IP地址转换为长整型(unsigned long)的变量,127.0.0.1表示本机地址
    c. hton()函数:将整型变量从主机字节顺序转变成网络字节顺序(高位字节存放在内存的低地址处。)
    d. bind:将套接字serv_sock与IP地址和端口绑定在一起(存储在serv_addr中)
  3. 进入监听状态,等待用户发送请求
    listen(serv_sock, 20); //对serv_sock套接字进行监听,20表示最大允许20个用户请求排队
    让套接字处于被动监听状态。所谓被动监听,是指套接字一直处于“睡眠”中,直到客户端发起请求才会被“唤醒”
  4. 接收客户端请求
    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_size = sizeof(clnt_addr);
    int clnt_sock = accept(serv_sock, (struct sockaddr*)clnt_addr, &clnt_addr_size);
    用来接收客户端的请求。程序一旦执行到 accept() 就会被阻塞(暂停运行),直到客户端发起请求。
  5. 向客户端发送数据
    char str[] = "Hello World!";
    write(clnt_sock, str, sizeof(str));
  6. 关闭套接字
    close(clnt_sock);
    close(serv_sock);

完整的服务端socket代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(){
    //创建套接字
    int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    //将套接字和IP、端口绑定
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
    serv_addr.sin_family = AF_INET;  //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
    serv_addr.sin_port = htons(1234);  //端口
    bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

    //进入监听状态,等待用户发起请求
    listen(serv_sock, 20);

    //接收客户端请求
    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_size = sizeof(clnt_addr);
    int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);

    //向客户端发送数据
    char str[] = "Hello World!";
    write(clnt_sock, str, sizeof(str));

    //关闭套接字
    close(clnt_sock);
    close(serv_sock);
    return 0;
}

服务器端代码:

客户端

 1 #include<stdio.h>
 2 #include<unistd.h>
 3 #include<sys/types.h>
 4 #include<sys/socket.h>
 5 #include<netinet/in.h>
 6 #include<netdb.h>
 7 #include<time.h>
 8 #include<string.h>
 9 #define PORTNUM 15000
10 #define HOSTLEN 256
11 #define oops(msg) {printf("error:%sn",msg);return 1;}
12 int main(int ac,char * av[]){
13     struct sockaddr_in saddr;
14     struct hostent * hp;
15     char hostname[HOSTLEN];
16     int sock_id,sock_fd;
17     FILE * sock_fpi,* sock_fpo;
18     FILE * pipe_fp;
19     char dirname[BUFSIZ];
20     char command[BUFSIZ];
21     int dirlen,c;
22     sock_id=socket(PF_INET,SOCK_STREAM,0);//set socket
23     if(sock_id==-1)
24         oops("socket");
25     bzero((void *)&saddr,sizeof(saddr));//empty saddr
26     gethostname(hostname,HOSTLEN);
27     printf("hostname:%sn",hostname);
28     hp=gethostbyname(hostname);
29     bcopy((void *)hp->h_addr,(void *)&saddr.sin_addr,hp->h_length);
30     saddr.sin_port=htons(PORTNUM);
31     saddr.sin_family=AF_INET;
32     if(bind(sock_id,(struct sockaddr *)&saddr,sizeof(saddr))!=0)//bind address
33         oops("bind");
34     if(listen(sock_id,1)!=0)//listen
35         oops("listen");
36     while(1){
37         sock_fd=accept(sock_id,NULL,NULL);//start accept
38         if(sock_fd==-1)
39             oops("accept");
40         if((sock_fpi=fdopen(sock_fd,"r"))==NULL)
41             oops("fdopen reading");
42         if(fgets(dirname,BUFSIZ-5,sock_fpi)==NULL)
43             oops("reading dirname");
44         sanitize(dirname);
45         if((sock_fpo=fdopen(sock_fd,"w"))==NULL)
46             oops("fdopen writing");
47         sprintf(command,"ls %s",dirname);
48         if((pipe_fp=popen(command,"r"))==NULL)
49             oops("popen");
50         while((c=getc(pipe_fp))!=EOF)
51             putc(c,sock_fpo);
52         pclose(pipe_fp);
53         pclose(sock_fpo);
54         pclose(sock_fpi);
55     }
56 }
57 sanitize(char * str){
58     char * src,* dest;
59     for(src=dest=str;*src;src++)
60         if(*src=='/'||isalnum(*str))
61             *dest++=*src;
62     *dest='';
63 }

步骤

  1. 创建一个套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);
  2. 创建需要连接的服务器的sockaddr_in结构体的变量,并配置相应的参数,然后连接
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr)); //每个字节都用0填充
    serv_addr.sin_family = AF_INET; //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //因为我们连接的服务器端在本机上,所以该地址为本机地址
    serv_addr.sin_port = htons(1234); //端口
    connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    注:connect向服务器发起请求,服务器的IP地址和端口号保存在 sockaddr_in 结构体中。直到服务器端返回数据,connect才结束。
  3. 读取服务器端返回的数据
    char bufRecv[100] = {0};
    read(sock, bufRecv, 100);
    printf("Message form server: %sn", bufRecv);
  4. 关闭套接字
    close(sock);

完成的代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main(){
    //创建套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);

    //向服务器(特定的IP和端口)发起请求
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
    serv_addr.sin_family = AF_INET;            //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
    serv_addr.sin_port = htons(1234);  //端口
    connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

    //读取服务器传回的数据
    char buffer[40];
    read(sock, buffer, sizeof(buffer)-1);
    printf("Message form server: %sn", buffer);

    //关闭套接字
    close(sock);
    return 0;
}

客户端代码:

 1 #include<stdio.h>
 2 #include<linux/types.h>
 3 #include<sys/socket.h>
 4 #include<netinet/in.h>
 5 #include<netdb.h>
 6 #define oops(msg) {printf("error:%sn",msg);return 1;}
 7 #define PORTNUM 15000
 8 main(int ac,char * av[]){
 9     struct sockaddr_in servadd;
10     struct hostent * hp;
11     int sock_id,sock_fd;
12     char message[BUFSIZ];
13     char buffer[BUFSIZ];
14     int messlen,n_read;
15     sock_id=socket(PF_INET,SOCK_STREAM,0);//attention:PF_INT NOT AF_INT
16     if(sock_id==-1)
17         oops("socket");
18     bzero(&servadd,sizeof(servadd));
19     hp=gethostbyname(av[1]);
20     if(hp==NULL)
21         oops(av[1]);
22     bcopy(hp->h_addr,(struct sockaddr *)&servadd.sin_addr,hp->h_length);
23     servadd.sin_port=htons(PORTNUM);
24     servadd.sin_family=AF_INET;
25     if(connect(sock_id,(struct sockaddr *)&servadd,sizeof(servadd))!=0)//connect
26         oops("connect");
27     if(write(sock_id,av[2],strlen(av[2]))==-1)
28         oops("write");
29     if(write(sock_id,"n",1)==-1)
30         oops("write");
31     while((n_read=read(sock_id,buffer,BUFSIZ))>0)
32         if(write(1,buffer,n_read)==-1)
33             oops("write");
34         close(sock_id);
35 }

调用如下:

服务器启动:./rlsd&

客户端访问:./rls jsonzhang-Vostro-23-3340 ~/桌面/workplace/

编辑:操作系统 本文来源:然后就可以再程序中使用socket代理来编写程序了

关键词:

  • 上一篇:没有了
  • 下一篇:没有了