Socket 基础编程(一)

来源:互联网 发布:asp.net vb.net控件 编辑:程序博客网 时间:2024/05/18 00:54

这里写图片描述

一个通常意义上的Socket一般是分为Client与Server。
Server端需要实现:建立Socket-》绑定端口-》监听端口-》处理建链请求-》数据交互-》关闭链接。
Client端相对简单些:建立Socket-》发起TCP建链-》发送数据请求-》数据交互-》关闭链接。

如下是各API函数对应的TCP业务动作:
这里写图片描述

Client 的connect对应的TCP中的SYN建联请求,而服务器的accept对应的就是SYN ACK。
当Server端Accept成功后,会新分配一个fd用于和客户端做数据交互。
Close函数,则对应了四次挥手的动作。

如下是一简单的Server与Client实现:

Server:

#include <stdio.h>#include <stdlib.h>#include <memory.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#define SUCCESS 4#define SERVERPORT 8888#define SOCKMAXCONN 1024int main(){       char buffer[1024] = {0};    struct sockaddr_in client_socket_addr;    struct sockaddr_in server_socket_addr;    socklen_t length = sizeof(client_socket_addr);    //////////////////////////////////////////////////////////////////////////////    //  struct sockaddr_in {    //      __kernel_sa_family_t    sin_family; /* Address family */    //      __be16      sin_port;   /* Port number */    //      struct in_addr  sin_addr;   /* Internet address */    //      unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) - sizeof(unsigned short int) - sizeof(struct in_addr)];    //  };    ///////////////////////////////////////////////////////////////////////////////    server_socket_addr.sin_family = AF_INET;    server_socket_addr.sin_port = htons(SERVERPORT);    server_socket_addr.sin_addr.s_addr = htonl(INADDR_ANY);    //////////////////////////////////////////////////////////////////////////////    //  Create a new socket of type TYPE in domain DOMAIN, using    //  protocol PROTOCOL.  If PROTOCOL is zero, one is chosen automatically.    //  Returns a file descriptor for the new socket, or -1 for errors.    //  extern int socket (int __domain, int __type, int __protocol) __THROW;    ///////////////////////////////////////////////////////////////////////////////    int server_socket_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    ///////////////////////////////////////////////////////////////////////////////    //  Give the socket FD the local address ADDR (which is LEN bytes long).     //  extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)    ///////////////////////////////////////////////////////////////////////////////    if (SUCCESS != bind(server_socket_fd, (struct sockaddr *)&server_socket_addr, sizeof(server_socket_addr)))    {        perror ("Bind Socket Failed: ");        goto exit_half;    }    ///////////////////////////////////////////////////////////////////////////////    //  Prepare to accept connections on socket FD.    //  N connection requests will be queued before further requests are refused.    //  Returns 0 on success, -1 for errors.    //  extern int listen (int __fd, int __n) __THROW;    ///////////////////////////////////////////////////////////////////////////////    if(SUCCESS != listen(server_socket_fd, SOCKMAXCONN))    {        perror ("Listen Socket Failed: ");        goto exit_half;    }    ///////////////////////////////////////////////////////////////////////////////    //  A wait a connection on socket FD.    //  When a connection arrives, open a new socket to communicate with it,    //  set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting    //  peer and *ADDR_LEN to the address's actual length, and return the    //  new socket's descriptor, or -1 for errors.    //  This function is a cancellation point and therefore not marked with __THROW.    //  extern int accept (int __fd, __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len);    ///////////////////////////////////////////////////////////////////////////////    int client_conn = accept(server_socket_fd, (struct sockaddr*)&client_socket_addr, &length);    if (-1 == client_conn)    {        perror ("Connect Socket Failed: ");        goto exit_half;    }    ///////////////////////////////////////////////////////////////////////////////    //  Read N bytes into BUF from socket FD.    //  Returns the number read or -1 for errors.    //  This function is a cancellation point and therefore not marked with __THROW.     //  extern ssize_t recv (int __fd, void *__buf, size_t __n, int __flags);    ///////////////////////////////////////////////////////////////////////////////    int client_len = recv(client_conn, buffer, sizeof(buffer), 0);    if (-1 == client_len)    {        perror ("Recv Socket Failed: ");        goto exit;    }    ///////////////////////////////////////////////////////////////////////////////    //  Send N bytes of BUF to socket FD.  Returns the number sent or -1.    //  This function is a cancellation point and therefore not marked with __THROW.    //  extern ssize_t send (int __fd, const void *__buf, size_t __n, int __flags);    ///////////////////////////////////////////////////////////////////////////////    if (-1 == send(client_conn, buffer, client_len, 0))    {        perror ("Send Socket Failed: ");        goto exit;    }    printf("Received Request: %s !\n", buffer);    goto exit;exit:    //////////////////////////////////////////////////////////////////////////////    //  Close the file descriptor FD.    //  This function is a cancellation point and therefore not marked with    //  __THROW.    //  extern int close (int __fd);      //////////////////////////////////////////////////////////////////////////////        close(client_conn);    close(server_socket_fd);     return SUCCESS;  exit_half:    close(server_socket_fd);     return SUCCESS;  }

Client:

#include <stdio.h>#include <stdlib.h>#include <memory.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#define SUCCESS 0#define SERVERPORT 8888int main(){       char buffer[1024] = {0};    char *send_msg = "Hello World!";    struct sockaddr_in server_socket_addr = {0};    socklen_t server_addr_length = sizeof(server_socket_addr);    server_socket_addr.sin_family = AF_INET;    server_socket_addr.sin_port = htons(SERVERPORT);    if( inet_pton(AF_INET, "127.0.0.1", &server_socket_addr.sin_addr) <= 0)    {        perror ("Inet_pton Socket Failed: ");        goto exit;    }    //////////////////////////////////////////////////////////////////////////////    //  Create a new socket of type TYPE in domain DOMAIN, using    //  protocol PROTOCOL.  If PROTOCOL is zero, one is chosen automatically.    //  Returns a file descriptor for the new socket, or -1 for errors.    //  extern int socket (int __domain, int __type, int __protocol) __THROW;    ///////////////////////////////////////////////////////////////////////////////    int client_socket_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    //////////////////////////////////////////////////////////////////////////////    //  Open a connection on socket FD to peer at ADDR (which LEN bytes long).    //  For connectionless socket types, just set the default address to send to    //  and the only address from which to accept transmissions.    //  Return 0 on success, -1 for errors.    //  This function is a cancellation point and therefore not marked with __THROW.    //  extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);    //////////////////////////////////////////////////////////////////////////////    if(SUCCESS != connect (client_socket_fd, (struct sockaddr*)&server_socket_addr, server_addr_length))    {        perror ("Connect Socket Failed: ");        goto exit;    }    ///////////////////////////////////////////////////////////////////////////////    //  Send N bytes of BUF to socket FD.  Returns the number sent or -1.    //  This function is a cancellation point and therefore not marked with __THROW.    //  extern ssize_t send (int __fd, const void *__buf, size_t __n, int __flags);    ///////////////////////////////////////////////////////////////////////////////    if (-1 == send(client_socket_fd, send_msg, strlen("Hello World!"), 0))    {        perror ("Send Socket Failed: ");        goto exit;    }    ///////////////////////////////////////////////////////////////////////////////    //  Read N bytes into BUF from socket FD.    //  Returns the number read or -1 for errors.    //  This function is a cancellation point and therefore not marked with __THROW.     //  extern ssize_t recv (int __fd, void *__buf, size_t __n, int __flags);    ///////////////////////////////////////////////////////////////////////////////    int client_len = recv(client_socket_fd, buffer, sizeof(buffer), 0);    if (-1 == client_len)    {        perror ("Recv Socket Failed: ");        goto exit;    }    printf("Received Response: %s !\n", buffer);    send(client_socket_fd, "BYE", strlen("BYE"), 0);    goto exit;exit:    close(client_socket_fd);      return SUCCESS;  }
0 0
原创粉丝点击