zoukankan      html  css  js  c++  java
  • Socket编程

    Socket编程很简单。因为不管用什么语言、什么环境编写,都是那几个固定的步骤。

    Socket可以通过TCP\IP和UDP两种方式实现。

    TCP\IP

      tcp建立连接要进行“三次握手”,即交换三个分组。大致流程如下:

    • 客户端向服务器发送一个SYN J
    • 服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1
    • 客户端再想服务器发一个确认ACK K+1

      当客户端调用connect时,触发了连接请求,向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手完毕,连接建立。

    Linux下实现,看下面的例子。windows下微软已经封装很好了,更简单一些,这里不赘述。

    一、Server端。

    View Code
    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <fcntl.h>
    #include <string.h>
    
    
    int open_file(const char* filename)
    {
            int fd;
    
            if ((fd = open(filename, O_CREAT | O_RDWR, 0666)) < 0) {
                    printf("open error");
    		return 0;
            }
            else {
            //        printf("Open file%d\n", fd);
            }
    
            return fd;
    }
    
    void write_file(int fd, char *buf, int len)
    {
    	lseek(fd, 0, SEEK_END);
            if (write(fd, buf, len) < 0) {
                    printf("write error");
            }
            else {
            //        printf("Write: %s\n", buf);
            }
    }
    
    void read_file(int fd, int len)
    {
            char buff[len + 1];
    
            lseek(fd, 0, SEEK_SET);
            if (read(fd, buff, len) < 0) {
                    printf("read error");
            }
            else {
                    buff[len] = '\0';
              //      printf("read from file: %s\n", buff);
            }
    }
    
    void close_file(int fd)
    {
            if (close(fd) < 0) {
                    printf("close error");
            }
            else 
    	{//do nothing, close file right
            }
    }
    
    int main(int argc, char *argv[])
    {
        // Get Port option
        if (argc < 2)
        {
            fprintf(stderr, "ERROR, no port provided\n");
            exit(1);
        }
        int port_no = atoi(argv[1]);
    
        // Get socket
        int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    
        // Bind
        struct sockaddr_in server_addr;
        bzero((char *) &server_addr, sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = INADDR_ANY;
        server_addr.sin_port = htons(port_no);
        bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr));
    
        // Listen
        listen(socket_fd, 5);
    
        while (1) {
    
            // Accept
            struct sockaddr_in client_addr;
            socklen_t client_addr_length = sizeof(client_addr);
            int socket_to_client = accept(socket_fd, (struct sockaddr *) &client_addr, &client_addr_length);
    
            // Read the buffer from the socket
            char buffer[1024*10240];
            bzero(buffer, sizeof(buffer));
            read(socket_to_client, buffer, sizeof(buffer) - 1);
        //上面这个函数可以用下面的这个代替
        //recv(socket_toclient, buffer, sizeof(buffer)-1, 0);
    //printf("Here is the message: %s\n", buffer); //write the string into the file int fd = open_file("server.log"); if(fd > 0) { int len = strlen(buffer); write_file(fd, buffer, len); close_file(fd); } // Write const char *data = "I got your message."; write(socket_to_client, data, strlen(data)); // Close close(socket_to_client); } close(socket_fd); return 0; }

      

    二、Client端。

    View Code
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <stdio.h>
    #include <string.h>
    #include <netdb.h> // bcopy
    #include <stdlib.h>

    int main(int argc, char *argv[])
    {
      // Get options
      if (argc < 3)
      {
        fprintf(stderr, "Usage: %s <hostname> <port>\n", argv[0]);
        exit(1);
      }
      struct hostent *server_host = gethostbyname(argv[1]);
      int server_port = atoi(argv[2]);

      // Get socket
      int socket_fd = socket(AF_INET, SOCK_STREAM, 0);

      // Connect
      struct sockaddr_in server_addr;
      bzero((char *) &server_addr, sizeof(server_addr));
      server_addr.sin_family = AF_INET;
      bcopy((char *) server_host->h_addr, (char *) &server_addr.sin_addr.s_addr, server_host->h_length);
      server_addr.sin_port = htons(server_port);
      connect(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr));

      // Input
      printf("Please enter the message: ");
      char buffer[1024];
      bzero(buffer, sizeof(buffer));
      fgets(buffer, sizeof(buffer) - 1, stdin);

      // Write
      write(socket_fd, buffer, strlen(buffer));

      // Read
      bzero(buffer, sizeof(buffer));
      read(socket_fd, buffer, sizeof(buffer) - 1);
      printf("%s\n", buffer);

      // Close
      close(socket_fd);

      return 0;
    }


     1 #include <sys/socket.h>
    2 #include <netinet/in.h>
    3 #include <stdio.h>
    4 #include <string.h>
    5 #include <netdb.h> // bcopy
    6 #include <stdlib.h>
    7
    8 int main(int argc, char *argv[])
    9 {
    10 // Get options
    11 if (argc < 3)
    12 {
    13 fprintf(stderr, "Usage: %s <hostname> <port>\n", argv[0]);
    14 exit(1);
    15 }
    16 struct hostent *server_host = gethostbyname(argv[1]);
    17 int server_port = atoi(argv[2]);
    18
    19 // Get socket
    20 int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    21
    22 // Connect
    23 struct sockaddr_in server_addr;
    24 bzero((char *) &server_addr, sizeof(server_addr));
    25 server_addr.sin_family = AF_INET;
    26 bcopy((char *) server_host->h_addr, (char *) &server_addr.sin_addr.s_addr, server_host->h_length);
    27 server_addr.sin_port = htons(server_port);
    28 connect(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr));
    29
    30 // Input
    31 printf("Please enter the message: ");
    32 char buffer[1024];
    33 bzero(buffer, sizeof(buffer));
    34 fgets(buffer, sizeof(buffer) - 1, stdin);
    35
    36 // Write
    37 write(socket_fd, buffer, strlen(buffer));
    38
    39 // Read
    40 bzero(buffer, sizeof(buffer));
    41 read(socket_fd, buffer, sizeof(buffer) - 1);
    42 printf("%s\n", buffer);
    43
    44 // Close
    45 close(socket_fd);
    46
    47 return 0;
    48 }

    UDP

    看例子代码。

    Server端。

    View Code

    Client端。

    View Code
     1 #include <sys/socket.h>
    2 #include <string.h>
    3 #include <netinet/in.h>
    4 #include <netdb.h>
    5
    6 int main(int argc, char *argv[])
    7 {
    8 // Create socket
    9 int socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
    10
    11 // Initialize server address
    12 struct hostent *server_host = gethostbyname(argv[1]);
    13 struct sockaddr_in server_addr;
    14 server_addr.sin_family = AF_INET; // socket internet family
    15 bcopy((char *)server_host->h_addr, (char *)&server_addr.sin_addr.s_addr, server_host->h_length); // socket internet address
    16 server_addr.sin_port = htons(atoi(argv[2])); // socket internet port
    17
    18 // Send
    19 char buffer[1024];
    20 sendto(socket_fd, buffer, sizeof(buffer), 0, (const struct sockaddr *) &server_addr, sizeof(struct sockaddr_in));
    21
    22 // Receive and write
    23 struct sockaddr_in client_addr;
    24 socklen_t client_addr_length = sizeof(client_addr);
    25 int msg_recv_length = recvfrom(socket_fd, buffer, sizeof(buffer), 0, (struct sockaddr *) &client_addr, &client_addr_length);
    26 const char *hint = "Got an ACK: ";
    27 write(1, hint, strlen(hint));
    28 write(1, buffer, msg_recv_length);
    29
    30 // Close
    31 close(socket_fd);
    32
    33 return 0;
    34 }



  • 相关阅读:
    [bzoj4893]项链分赃
    [Spoj]Counting Divisors (cube)
    [Noi2016]国王饮水记
    [Noi2016]网格
    [Noi2016]优秀的拆分
    [Noi2016]区间
    [Noi2015]寿司晚宴
    Codeforces Round #411 (Div. 2)
    VK-Cup2017 Wild Card Round 2
    [Noi2015]小园丁和老司机
  • 原文地址:https://www.cnblogs.com/flysnail/p/2419911.html
Copyright © 2011-2022 走看看