1.Socket通信

以下からの情報とガイダンスについては、このブログの内容の一部C言語中国のネットワーク

サーバー側、二:クライアントソケット通信に最初の二つの概念、最初に理解する必要があります。(二つの異なるクライアント間の差。クライアントサービス用のサーバー、クライアントは、両者の間に大きく異なる奉仕する真の「顧客」であるが、密接にリンクされ、クライアントがパーティを要求していますまたは発信元は命令であり、サーバが応答者です。)

サーバー側:名前が示唆するように、要求が応答オブジェクトに基づいて、サーバー側の処理にクライアントから送信されたサービスは、サーバー側の処理は、クライアントに完了し、存在しています。

クライアント:ウェブの存在下では、この方法がのJavaEEのServletRequestおよびそのサブクラスで特定の用途を見出すことができる、サーバ・プロセスに要求を送信し、要求オブジェクトです。

一般的に、我々はサイトを訪問し、(ブラウザ、アプリ)を要求し、他のサーバ(シーナ、捜狐)応答を行うクライアントが、結果は私たちにページパスを返され、我々は再びパスに応じてWebページを参照してください。

//服务器端代码  server.cpp
#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);//参数分别是IPV4,面向连接套接字,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地址//将一个字符串的IP转换成一个长整型
    serv_addr.sin_port = htons(1234);  //端口 //将整数转换为网络字节
    bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));//将address指向的sockaddr结构体中描述的一些属性(IP地址、端口号、地址簇)与socket套接字绑定,也叫给套接字命名。

//采用TCP通信时,客户端不需要bind()他自己的IP和端口号,而服务器必须要bind()自己本机的IP和端号;
/*因为服务器是时时在监听有没有客户端的连接,如果服务器不绑定IP和端口的话,客户端上线的时候怎么连到服务器呢,所以服务器要绑定IP和端口,而客户端就不需要了,客户端上线是主动向服务器发出请求的,因为服务器已经绑定了IP和端口,所以客户端上线的就向这个IP和端口发出请求,这时因为客户开始发数据了(发上线请求),系统就给客户端分配一个随机端口,这个端口和客户端的IP会随着上线请求一起发给服务器,服务收到上线请求后就可以从中获起发此请求的客户的IP和端口,接下来服务器就可以利用获起的IP和端口给客户端回应消息了。*/

    //进入监听状态,等待用户发起请求
    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[] = "http://c.biancheng.net/socket/";
    write(clnt_sock, str, sizeof(str));
   
    //关闭套接字
    close(clnt_sock);
    close(serv_sock);

    return 0;
}
//客户端代码  client.cpp
#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: %s\n", buffer);
   
    //关闭套接字
    close(sock);

    return 0;
}

ターミナル([スタートシェル)、コンパイルして実行server.cpp:

$ G ++ server.cpp -oサーバー
$ ./server

通常の状況下では、プログラムは、(受け入れるように動作します)関数は、要求を開始したクライアントを待って、ブロックされます。

ターミナル、コンパイルと実行client.cppを再起動しました:

$ G ++ client.cpp -oクライアント
の$ ./clientの
メッセージフォームサーバー:http://c.biancheng.net/socket/

クライアントは、文字列は、端の上で実行するために、サーバから送信されると同時に、サーバも轢か完全なタスクに文字列を送信受けます。これは、2つのオープン端末によって観察することができます。

CONNECT()関数を介してクライアントを実行すると、サーバ要求を開始する後、リスニング状態にサーバが起動され、()関数は、クライアント要求を受け付けて、書き込み()関数は、クライアントにデータを返す実行受け入れる実行。クライアントが実行の最後に返されたデータを、接続()を受信した後で、()のデータを読み出すために読んでください。

サーバは、サーバがクライアントにデータを返すとき、プログラムが上で実行されます、クライアントの要求を受け付けます。あなたは、データ・サーバに再び受信したい場合は、クライアントの要求を受け入れることができていない、再びサーバーを実行する必要があります。

 

PS:

ネットワークプログラミング・インターフェース------ソケットとファイル記述子を作成します。「場所」以下のニーズがソケット「場所」(TCP)に配置されるように、定義されている、彼らはしっかりと結ばれます、それにバインド機能、関数のプロトタイプで見てみましょう:

int型PASCAL FARバインド(SOCKET s、constの構造体のsockaddr FAR * addrは、int型NAMELEN)。

     もちろん、最初の引数が二番目の引数は、三番目のパラメータは、大きさの領域における「場所」である「場所」、識別するためにバインドされ、ソケット友達になるにバインドされています。

     戻り値は、結合操作が成功したかどうかを示し、0は成功のために、-1、失敗を示しています。関数の戻り値を無視してはいけない、と言った最後の人でした。

 

    一般的に、いわゆる:

     IRET =バインド(sockSrv、(SOCKADDR *)&addrSrv、はsizeof(SOCKADDR)); //注キャスト

 

     のは、ファイルI / O操作とネットワークI / O操作を比較してみましょう:、ファイルを開くファイルを読み込むことができるようになりますと、書き込みが、ネットワークI / Oは、この機能を完了するための3つのステップが実際にあります。

     1. /ソケットを作成します。

     2.名前ソケットは、我々は知っている、ソケット名は、バインドとバインド一緒にこれらの三つの要素のソケット関数を呼び出すことによって命名された「プロトコル、IPアドレス、ポート番号」これらの3つの要素が含まれています。

     接続を確立3.

()関数を受け入れます

リスニングステートのソケットは、クライアントが受け入れる()関数の要求によって受信される場合があります。そのプロトタイプは次のとおりです。

int accept(int sock, struct sockaddr *addr, socklen_t *addrlen);  //Linux
SOCKET accept(SOCKET sock, struct sockaddr *addr, int *addrlen);  //Windows

そのパラメータとlisten()と接続()は同じである:靴下サーバ側ソケット、addrが構造変数SOCKADDR_INであり、パラメータADDR addrlenは長さはsizeof()によって得られます。

()クライアント、クライアントのIPアドレスとポート番号の保存addrで通信するための新しいソケットを返し、受け入れ靴下は、サーバー側のソケットがある一方で、我々は区別に注意してください。リアとクライアントの通信は、ソケットの新世代を使用する場合は、代わりに元のサーバーのソケット。

ちょうど()受け入れるまで実行を継続しますリスニング状態にソケットは、実際に、クライアントの要求を受信聞く()のコードの後ろにいませんしましょう()聞く:最後に、留意すべきです。受け入れる()(コードを実行することはできません後)新しい要求が来るまで、実行をブロックします。

 

公開された28元の記事 ウォンの賞賛4 ビュー10000 +

おすすめ

転載: blog.csdn.net/m0_37957160/article/details/103525679