澳门皇冠金沙网站-澳门皇冠844网站

热门关键词: 澳门皇冠金沙网站,澳门皇冠844网站

客户端调用服务端webservice的端口问题,用C编写一

客户端调用劳动端webservice的端口难点,服务端webservice

       明日有叁个同事过来问:他有二个先后在A服务器上调第三方B服务器短信发送服务接口(webservice),无论是或不是发送成功,服务接口都会再次回到状态。以后客户要做每二个服务器

做入站端口管理调整,一切不供给的端口都要禁掉,问那边需求开放哪些入站端口,前提不要影响短信的出殡和情景重返。同事说连接时己方的发生的端口号是随便的,不理解怎么过来用户。

       那一个标题看起来又简便又新鲜,容易的是感到禁止使用入站端口未有怎么影响,特殊的是只要做了限定,状态音信重返不了。实则那么些难题就是非常粗大略的,要明白入站和出站的实际含义,

入站钦命的是第三方向己方发起连接乞求,如若此刻禁止使用端口,那么就一直无法完毕握手。出站就是扭曲。对于地点所说,我们那是出站诉求,只要不禁止访谈对方的端口就行了。

      看来本身大概对TCP/IP依然面生呀!

前几日有叁个同事过来问:他有一个先后在A服务器上调第三方B服务器短信发送服务接...

       那么些难点看起来又简便又极其,轻松的是认为禁止使用入站端口未有怎么震慑,特殊的是一旦做了限制,状态音信重返不了。实则这些难题正是相当粗略的,要明白入站和出站的实际意思,

全体的服务器代码

#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
int main()
{
    int server_sockfd = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);

    if(server_sockfd == -1){
        printf("socket error");
        return -1;
    }

    struct sockaddr_in server_sockaddr;/*声明一个变量,类型为协议地址类型*/
    server_sockaddr.sin_family = AF_INET;/*使用IPv4协议*/
    server_sockaddr.sin_port = htons(8887);/*监听8887端口*/
    server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*绑定本机IP,使用宏定义绑定*/

    if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1){
        printf("bind error");
        return -1;
    }

    if(listen(server_sockfd, 20) == -1){
        printf("listen error");
        return -1;
    }

    struct sockaddr_in clnt_addr;/*只是声明,并没有赋值*/
    socklen_t clnt_addr_size = sizeof(clnt_addr);
    int clnt_sock = accept(server_sockfd, (struct sockaddr*)&clnt_addr, &clnt_addr_size);

    if(clnt_sock == -1){
        printf("appect error");
        return -1;
    }

    char str[] = "Hello World";
    write(clnt_sock, str, sizeof(str));

    close(clnt_sock);
    close(server_sockfd);
}

      看来本人也许对TCP/IP仍旧素不相识呀!

socket函数

为了推行互连网I/O,八个经过必须做的率先件业务便是创制一个socket函数,函数原型

# family 表示协议族
# type 表示套接字类型
# protocol 表示传输协议
# 若成功返回非负描述符,若出错返回-1
int socket(int family, int type, int protocol);

其一函数须求传入协议族,套接字类型,传输层协议三个参数。

协议族可以有以下取值

family 说明
AF_INET IPv4协议
AF_INET6 IPv6协议
AF_LOCAL Unix域协议
AF_ROUTE 路由套接字
AF_KEY 密钥套接字

套接字类型能够有以下取值

type 说明
SOCK_STREAM 字节流套接字
SOCK_DGRAM 数据报套接字
SOCK_SEQPACKET 有序分组套接字
SOCK_ROW 原始套接字

传输层协议得以有以下取值

protocol 说明
IPPROTO_TCP TCP传输协议
IPPROTO_UDP UDP传输协议
IPPROTO_SCTP SCTP传输协议

此地大家选用IPv4共谋,使用字节流套接字,传输层选用TCP协议,所以率先段代码:

#include <stdio.h>
#include <sys/socket.h>
int main()
{
    int server_sockfd = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);

    if(server_sockfd == -1){
        printf("socket error");
        return -1;
    }
}

       后天有叁个同事过来问:他有二个先后在A服务器上调第三方B服务器短信发送服务接口(webservice),无论是或不是发送成功,服务接口都会回来状态。今后客户要做每一个服务器

accept函数

accept函数是由TCP服务器调用,用于从已做到连接队列的队头再次回到下三个已成功连接,如若已成功连接队列为空,那么进度步入梦眠形式,函数原型

# sockdf 服务器套接字莫描述符
# cliaddr 已连接的客户端协议地址
# addrlen 已连接的客户端协议地址长度
# 成功返回非负描述符,出错返回-1
int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);

当accept成功时,重回值是由基本自动生成的全新描述符,代表与所重返的客户端TCP连接。所以,在我们研商accept函数时,大家称第一个参数为监听套接字,它的再次回到值是已连接套接字,多个服务器一般指创制三个监听套接字(常常是80端口),内核为每种由服务器进度接受的客户端连接创造多个已连接套接字,当服务器实现对某些给定的客户端服务时,连接就能够被关闭。

函数的第四个参数也是两个共谋地址结构体,那一个结构体和服务端协议地址是同二个结构体。大家得以不关切客户端的磋商,直接传空,我们关系的是以此函数的重回值,因为它回到的是客户端连接描述符,大家能够对这些描述符进行写操作,进而达成给客户端传输数据。所以大家第四段代码

#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
int main()
{
    int server_sockfd = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);

    if(server_sockfd == -1){
        printf("socket error");
        return -1;
    }

    struct sockaddr_in server_sockaddr;/*声明一个变量,类型为协议地址类型*/
    server_sockaddr.sin_family = AF_INET;/*使用IPv4协议*/
    server_sockaddr.sin_port = htons(8887);/*监听8887端口*/
    server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*绑定本机IP,使用宏定义绑定*/

    if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1){
        printf("bind error");
        exit(1);
    }

    if(listen(server_sockfd, 20) == -1){
        printf("listen error");
        exit(1);
    }

    struct sockaddr_in clnt_addr;/*只是声明,并没有赋值*/
    socklen_t clnt_addr_size = sizeof(clnt_addr);
    int clnt_sock = accept(server_sockfd, (struct sockaddr*)&clnt_addr, &clnt_addr_size);

    if(clnt_sock == -1){
        printf("appect error");
        return -1;
    }

}

入站钦定的是第三主旋律己方发起连接央浼,假诺那时禁止使用端口,那么就根本无法兑现握手。出站正是扭曲。对于地点所说,大家那是出站诉求,只要不禁止访谈对方的端口就行了。

不间断提供劳务

让服务器平昔运行的方式极粗略,正是死循环。循环的进度是accept一个客户端连接,然后管理数量央求,最终关闭客户端连接。注意,我们不能够关闭服务端连接。所以大家立异那一个程序,让server不间断的调用accept,因为accept总是从已接连的队列中回到贰个连接,然后管理。创新内容片断

/**
 * 进入死循环调用accept,给每一个连接上来的客户端发送Hello World
 */
for( ; ; ){
    struct sockaddr_in clnt_addr;/*只是声明,并没有赋值*/
    socklen_t clnt_addr_size = sizeof(clnt_addr);
    int clnt_sock = accept(server_sockfd, (struct sockaddr*)&clnt_addr, &clnt_addr_size);

    if(clnt_sock == -1){
        printf("appect error");
        return -1;
    }

    char str[] = "Hello World";
    write(clnt_sock, str, sizeof(str));

    close(clnt_sock);
    /*close(server_sockfd);*/
}

那样修改以后,那么些服务端程序便是一向不间断提供服务了

做入站端口管理调节,一切不须要的端口都要禁掉,问那边须求开放哪些入站端口,前提不要影响短信的发送和状态重返。同事说连接时己方的产生的端口号是不管三七二十一的,不通晓怎么回复用户。

前言

正文使用C语言编写三个简短服务器,目的在于越来越好的了解服务端/客户端程序,迭代服务器,并发服务器等概念,仅供就学参照他事他说加以考察。这篇文章的事例很轻便,便是当客户端连接上服务端之后,服务端给出三个“Hello World”回应。

出现服务器

当叁个劳动管理客户端恳求要求开支较长期,不过大家又不希望任何服务器被单个客户端短时间占用,而是希望同有的时候候服务多少个客户。Unix中编辑并发服务器最简便的艺术正是fork一个子经过来服务每种客户。利用fork函数能够把拍卖客户端央求的任务衔接到子进程,那样就实现多进度并发,我们能够写出这么服务器的概貌

pid_t pid;
for( ; ; ){    
    struct sockaddr_in clnt_addr;/*只是声明,并没有赋值*/
    socklen_t clnt_addr_size = sizeof(clnt_addr);
    int clnt_sock = accept(server_sockfd, (struct sockaddr*)&clnt_addr, &clnt_addr_size);

    if(clnt_sock == -1){
        printf("appect error");
        return -1;
    }

    /**
     * 这一段直接fork一个子进程
     * 子进程处理单独处理完请求之后退出
     */
    if( (pid = fork()) == 0 ){
        close(server_sockfd);/*子进程不需要监听,关闭*/
        doit(clnt_sock);/*针对已连接的客户端套接字进行读写*/
        close(clnt_sock);/*处理完毕,关闭客户端连接*/
        exit(0);/*自觉退出*/
    }

    close(clnt_sock); /*连接已经交由子进程处理,父进程可以关闭客户端连接了*/
    /*close(server_sockfd);*/
}

里面,doit函数我们先不兑现,我们来看一下三个面世服务器管理三个客户端连接的流程

  1. 服务器阻塞于accept调用且来源客户的连天要求达到时的客户端与服务器的事态

image

  1. 从accept重临后,连接已经在基础中登记,并且新的套接口connfd被创设。那是贰个已建起接连的套接口,可以张开多少的读写。

image

3.并发服务器在调用fork之后,listenfd和connfd那多少个描述字在父过程以及子进度之间分享(实际为内部一份为copy)

image

  1. 接下去是由父进度关闭已连接套接口(connfd),由子进度关闭监听套接口(listenfd)。然后由子进度肩负为客户端提供劳动

image

最终大家的出现服务器代码为

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>

void doit(int sockfd);

int main()
{
    int server_sockfd = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
    pid_t pid;

    if(server_sockfd == -1){
        printf("socket error");
        return -1;
    }

    struct sockaddr_in server_sockaddr;/*声明一个变量,类型为协议地址类型*/
    server_sockaddr.sin_family = AF_INET;/*使用IPv4协议*/
    server_sockaddr.sin_port = htons(8887);/*监听8887端口*/
    server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*绑定本机IP,使用宏定义绑定*/

    if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1){
        printf("bind error");
        return -1;
    }

    if(listen(server_sockfd, 20) == -1){
        printf("listen error");
        return -1;
    }

    for( ; ; ){    
        struct sockaddr_in clnt_addr;/*只是声明,并没有赋值*/
        socklen_t clnt_addr_size = sizeof(clnt_addr);
        int clnt_sock = accept(server_sockfd, (struct sockaddr*)&clnt_addr, &clnt_addr_size);

        if(clnt_sock == -1){
            printf("appect error");
            return -1;
        }

        if( (pid = fork()) == 0 ){
            close(server_sockfd);/*子进程不需要监听,关闭*/
            doit(clnt_sock);/*针对已连接的客户端套接字进行读写*/
            close(clnt_sock);/*处理完毕,关闭客户端连接*/
            exit(0);/*自觉退出*/
        }    

        close(clnt_sock);
        /*close(server_sockfd);*/
    }
}

void doit(int sockfd){
    char str[] = "Hello World";
    sleep(3);//3秒之后再向客户端发送数据
    write(sockfd, str, sizeof(str));
}

本条时候重新利用shell并行实行大家的客户端,就能发掘,全数的Hello World是还要输出来的。这种服务器就能够形成飞快并且处理多个客户端连接。

运维客户端服务端

将大家的服务端代码保存为server.c,将大家的客户端代码保存为client.c。分别编写翻译客户端和服务端代码

[root@iZ940ofmvruZ socket]# gcc server.c -o server
[root@iZ940ofmvruZ socket]# gcc client.c -o client

接下来会分别生成七个可推行文件server和client。在二个窗口中先实践server

[root@iZ940ofmvruZ socket]# ./server

实践server之后,大家知道accept函数会阻塞,所以程序一贯运营,等待客户端连接进来。那时候在另多个窗口进行客户端

[root@iZ940ofmvruZ socket]# ./client 
Hello World

能够看到服务端给我们发送的Hello World,大家再回来服务端实施窗口时,服务端也停止了经过,那些互动完毕。然后大家会发现三个标题,服务端在提供完服务之后,它和谐也关闭了,很明显,我们期待服务器是一模一样运转的提供服务,所以大家须要贯彻间接运营的服务器

本文由澳门皇冠金沙网站发布于编辑程序,转载请注明出处:客户端调用服务端webservice的端口问题,用C编写一