zoukankan      html  css  js  c++  java
  • 网络编程(二)

     1、其他套接字操作函数(经常用于面向连接的通信过程和数据报通信过程):

    (1)getsockname函数用于返回本地套接字地址;

           int getsockname(int sockfd, struct sockaddr * address, socklen_t * address_len);

    (2)getpeername用于获取一个套接字的远程对等套接字的地址;

          int getpeername(int sockfd, struct sockaddr * address, socklen_t * address_len);

    (3)send函数用于向已连接的套接字发送数据;

         size_t send(int sockfd, const void * buffer, size_t length, int flags);

        参数flags指明消息传送的类型,它的值要么是0,此时这个函数等价于write;要么由下述标志按位逻辑或操作而形成

       参数flags的标志位:

    含义
    MSG_OOB 导致send发送的数据成为带外数据
    MSG_DONTROUTE 不在消息中包含路由信息

    (4)recv函数用于从已连接的套接字接收消息。

          size_t recv(int sockfd, void * buffer, size_t length, int flags);

    (5)read和write通常用来读写套接字上的普通数据,当需要发送或者接受特殊数据,如带外数据时,就必须使用send和recv才能做到。

    2、例子

    (1) StreamSocketClient2.c:发送带外数据的客户端程序

    /*
     * StreamSocketClient2.c
     *
     *  Created on: Aug 31, 2013
     *      Author: root
     */
    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    
    #define PORT 6666
    #define HOST_ADDR "127.0.0.1"
    
    int main(){
        int sockfd, n;
        struct sockaddr_in servaddr;
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if(sockfd < 0){
            printf("Socket created failed.
    ");
            return -1;
        }
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(PORT);
        inet_aton(HOST_ADDR, &servaddr.sin_addr);
        printf("connecting.......
    ");
        if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
            printf("Connect Error.
    ");
            return -1;
        }
        write(sockfd, "123",3);
        printf("wrote 3 byte of normal data.
    ");
        sleep(1);
        send(sockfd, "a", 1, MSG_OOB);
        printf("wrote 1 byte of OOB data.
    ");
        sleep(1);
        write(sockfd, "56",2);
        printf("wrote 2 byteof normal data.
    ");
        sleep(1);
        send(sockfd, "b", 1, MSG_OOB);
        printf("Wrote 1 byte of OOB data.
    ");
        sleep(1);
        write(sockfd, "89",2);
        printf("wrote 2 byte of normal data.
    ");
        sleep(1);
    
        return 0;
    }

    (2) StreamSocketServer2.c:接收带外数据的例子。

         以下的接收程序使用SIGURG信号来获得带外数据的通知。当一套接字发现有一带外数据在途中时,会发送SIGURG信号给此套接字的拥有线程或线程组;为了捕获该信号,首先要利用系统函数signal设定处理SIGURG信号的函数并且调用fcntl设置连接套接字的拥有者。

    /*
     * StreamSocketServer2.c
     *
     *  Created on: Aug 31, 2013
     *      Author: root
     */
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <signal.h>
    #include <fcntl.h>
    #include <unistd.h>
    #define LISTENQ 5
    int listenfd, connfd;
    void sig_urg(int signo);
    int main(){
        int n;
        char buff[100];
        socklen_t len;
        struct sockaddr_in servaddr, cliaddr;
        if(signal(SIGURG, sig_urg) == -1){
            printf("Couldn't register SIG_URG METHOD for SIGURG.
    ");
            return -1;
        }
        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        if(listenfd < 0){
            printf("Socket created failed.
    ");
            return -1;
        }
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(6666);
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
            printf("bind failed.
    ");
            return -1;
        }
        printf("listening ...
    ");
        listen(listenfd, LISTENQ);
        len = sizeof(cliaddr);
        connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &len);
        fcntl(connfd, F_SETOWN, getpid());   //设置连接套接字的拥有者
        while(1){
            if((n=read(connfd, buff, sizeof(buff))) == 0){
                printf("received EOF
    ");
                return 0;
            }
            buff[n] = 0;
            printf("read %d bytes : %s
    ", n,buff);
        }
    }
    
    void sig_urg(int signo){
        int n;
        char buffer[100];
        printf("SIGURG received
    ");
        n = recv(connfd,buffer, sizeof(buffer), MSG_OOB);
        buffer[n] = 0;
        printf("read %d OOB byte: %s
    ", n,buffer);
    }

     程序运行结果:

  • 相关阅读:
    搭建Java 开发环境
    自己制作 Android Vector Asset 矢量图
    Manifest merger failed with multiple errors, see logs 问题处理
    Android 获取所在城市(不接入地图SDK,使用android自带的SDK定位)
    根据视频地址获取封面
    Git 的一些使用细枝末节
    关于onActivityResult方法不执行的问题汇总
    关于handler 和 looper 的问题
    关于action和category的认知区别
    关于activity的生命周期的随笔
  • 原文地址:https://www.cnblogs.com/wangle1001986/p/3293112.html
Copyright © 2011-2022 走看看