1.Socket communication

Part of the contents of this blog for information and guidance from the C language Chinese network .

Into the socket communication must first understand the two concepts, first: the server side, the second: the client. (Difference between the two different clients. Server for client services, the client is a true "customers" to serve, so different between the two, but closely linked, the client is requesting party or the originator is the instruction, and the server is the responder.)

Server-side: As the name suggests is a service request sent by the client to the server-side processing, based on the response object exists, the server-side processing is completed back to the client.

Client: in the presence of the web is the request object, transmitting requests to the server process, the method may find particular use in javaee servletrequest and its subclasses.

Generally, we visit the site, are the client (browser, app) makes a request, then the other server (sina, sohu) response, the result is returned Page path to us, we again see the web page according to the path.

//服务器端代码  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;
}

Start a terminal ( Shell ), compile and run server.cpp:

$ g++ server.cpp -o server
$ ./server

Under normal circumstances, the program runs to accept () function will be blocked, waiting for the client initiated the request.

Took restart a terminal, compile and run client.cpp:

$ g++ client.cpp -o client
$ ./client
Message form server: http://c.biancheng.net/socket/

client receives the string is sent from the server to run over the end, at the same time, server sends the string to complete tasks also run over. It can be observed by two open terminals.

After the client runs through connect () function to initiate a server request, the server in the listening state is activated, executed accept () function accepts a client request and then performs write () function returns the data to the client. After the client receives the returned data, Connect () to the end of the run, then read () to read out the data.

server only accepts a client request, when the server returns data to the client, the program will run over. If you want to receive again to the data server, you must run the server again, not been able to accept the request of the client.

 

PS:

Create a network programming interface ------ file descriptor with socket. "Place" is defined, the following needs to be placed in the socket "place" (TCP), they will be tied tightly together, bind function with it, let's look at the function prototypes:

int PASCAL FAR bind (SOCKET s, const struct sockaddr FAR *addr, int namelen);

     The first argument of course is bound to be a socket friends, the second argument is bound to identify which "place", the third parameter is the "place" in an area of ​​the size.

     The return value indicates whether the binding operation is successful, 0 for success, -1 indicates unsuccessful. The return value of the function must not be ignored, was the last person to say.

 

    Generally so called:

     iRet = bind (sockSrv, (SOCKADDR *) & addrSrv, sizeof (SOCKADDR)); // Note casts

 

     Let's compare the file I / O operations and network I / O operations: open a file, the file will be able to read and write, but the network I / O There are actually three steps to complete this function:

     1. Open / Create a socket

     2. Name the socket, we know, socket name contains "protocol, ip address, port number" of these three elements, is named by calling the socket function bind and bind together these three elements.

     3. Establish connection

accept () function

When the socket in a listening state, the client may be received by the accept () function requests. Its prototype is:

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

Its parameters and listen () and connect () is the same: sock server side socket, addr is sockaddr_in structure variables, parameters addr addrlen the length, by the sizeof () is obtained.

accept () returns a new socket to communicate with clients, addr save the IP address and port number of the client, while the sock is a server-side socket, we note the distinction. When the rear and client communications, to use the new generation of sockets, socket instead of the original server.

Finally, it should be noted that: listen () just let the socket into the listening state, does not really receive client requests, listen () behind the code will continue to execute until accept (). accept () will block execution (after the code can not be executed), until a new request comes in.

 

Published 28 original articles · won praise 4 · views 10000 +

Guess you like

Origin blog.csdn.net/m0_37957160/article/details/103525679