zoukankan      html  css  js  c++  java
  • 网络编程入门

    Linux下网络编程

    socket函数

    #include <sys/socket.h>
    int socket(int domain, int type, int protocal);
    

    成功时返回文件描述符,失败时返回-1

    bind函数

    #include <sys/socket.h>
    int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen);
    

    成功时返回0,失败时返回-1

    listen函数

    #include <sys/socket.h>
    int listen(int sockfd, int backlog);
    

    成功时返回0,失败时返回-1

    accept函数

    #include <sys/socket.h>
    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    

    成功时返回0,失败时返回-1

    connect函数

    #include <sys/socket.h>
    int connect(int sockfd, struct sockaddr *serv_addr, socklen_t addrlen);
    

    成功时返回0,失败时返回-1

    open函数

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    int open(const char *path, int flag);
    

    成功时返回文件描述符,失败时返回-1

    打开模式 含义
    O_CREAT 必要时创建文件
    O_TRUNC 删除全部现有数据
    O_APPEND 维持现有数据,保存到其后面
    O_RDONLY 只读打开
    O_WRONLY 只写打开
    O_RDWR 读写打开

    close函数

    #include <unistd.h>
    int close(fd);
    

    成功时返回0,失败时返回-1

    write函数

    #include <unistd.h>
    ssize_t write(int fd, const void *buf, size_t nbytes);
    

    成功时返回写入的字节数,失败时返回-1
    - fd: 显示数据传输对象的文件描述符
    - buf: 保存要传输数据的缓冲地址值
    - nbytes: 要传输数据的字节数

    read函数

    #include <unistd.h>
    ssize_t read(int fd, void *buf, size_t nbytes);
    

    成功时返回接收的字节数(但遇到文件结尾则返回0),失败时返回-1
    - fd: 显示数据传输对象的文件描述符
    - buf: 要保存接收数据的缓冲地址值
    - nbytes: 要传输数据的字节数

    网络编程中接受连接请求的套接字创建过程可整理如下:

    • 调用socket函数创建套接字
    • 调用bind函数分配IP地址和端口号
    • 调用listen函数转为可接收请求状态
    • 调用accept函数受理连接请求

    server.cpp

    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <sys/socket.h>
    using namespace std;
    
    /*
     * 网络编程中接受连接请求的套接字创建过程可整理为:
     * 1. 调用socket函数创建套接字
     * 2. 调用bind函数分配IP地址和端口号
     * 3. 调用listen函数转为可接收请求状态
     * 4. 调用accept函数受理连接请求 
     * */
    
    void error_handling(string message);
    
    int main(int argc, char ** argv) {
      int serv_sock;
      int clnt_sock;
    
      struct sockaddr_in serv_addr;
      struct sockaddr_in clnt_addr;
      socklen_t clnt_addr_size;
    
      char message[] = "hello, world";
    
      if (argc != 2) {
        printf("Usage: %s <port>
    ", argv[0]);
        exit(1);
      }
    
      serv_sock = socket(PF_INET, SOCK_STREAM, 0);
      if (serv_sock == -1) 
        error_handling("socket() error");
    
      memset(&serv_addr, 0, sizeof(serv_addr));
      serv_addr.sin_family = AF_INET;
      serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
      serv_addr.sin_port = htons(atoi(argv[1]));
    
      if (bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
        error_handling("bind() error");
    
      if (listen(serv_sock, 5) == -1)
        error_handling("listen() error");
    
      clnt_addr_size = sizeof(clnt_addr);
      clnt_sock = accept(serv_sock, (struct sockaddr *)&clnt_addr,  &clnt_addr_size);
      if (clnt_sock == -1)
        error_handling("accept() error");
    
      write(clnt_sock, message, sizeof(message));
      close(clnt_sock);
      close(serv_sock);
      return 0;
    }
    
    void error_handling(string message) {
      cerr << message << endl;
      exit(1);
    }
    

    client.cpp

    #include <cerrno>
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <sys/socket.h>
    
    using namespace std;
    
    void error_handling(string message);
    
    int main(int argc, char ** argv) {
      int sock;
      struct sockaddr_in serv_addr;
      char message[30];
      int str_len;
    
      if (argc != 3) {
        cout << "Usage: " << argv[0] << " <IP> <port>" << endl;
        exit(1);
      }
    
      sock = socket(PF_INET, SOCK_STREAM, 0);
      if (sock == -1) 
        error_handling("socket() error");
    
      memset(&serv_addr, 0, sizeof(serv_addr));
      serv_addr.sin_family = AF_INET;
      serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
      serv_addr.sin_port = htons(atoi(argv[2]));
    
      if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) {
        close(sock);
        cout << "errno = " << errno << endl;
        error_handling("connect() error");
      }
    
      str_len = read(sock, message, sizeof(message) - 1);
      if (str_len == -1) {
        close(sock);
        error_handling("read() error");
      }
    
      cout << "Message from server: " << message << endl;
      close(sock);
      return 0;
    }
    void error_handling(string message) {
      cerr << message << endl;
      exit(1);
    }
    

    Windows下网络编程

    WSAStartup函数

    #include <winsock2.h>
    int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
    

    成功时返回0,失败时返回非0的错误代码值
    - wVersionRequested: 程序员要用的Winsock版本
    - lpWSAData: WSADATA结构体变量的地址值
    - 一般使用4位16进制数表示版本,高8位为副版本号,低8位为主版本号,如0x0201即表示主版本号为1副版本号为2的版本,即1.2版本,通常借助MAKEWORD宏函数MAKEWORD(1,2)表示1.2版本
    - lpWSADATA是WSADATA的指针类型

    WSAStartup函数调用过程

    int main(int argc, char ** argv) {
        WSADATA wsaData;
        ....
        if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) 
            error_handling("WSAStartup() error");
        ....
        return 0;
    }
    

    WSACleanup函数

    #include <winsock2.h>
    int WSACleanup(void);
    

    成功时返回0,失败时返回SOCKET_ERROR
    调用此函数时,Winsock相关库将归还Windows系统,无法再调用Winsock相关函数

    socket函数

    #include <winsock2.h>
    SOCKET socket(int af, int type, int protocal);
    

    成功时返回套接字句柄,失败时返回INVALID_SOCKET

    bind函数

    #include <winsock2.h>
    int bind(SOCKET s, const struct sockaddr *name, int namelen);
    

    成功时返回0,失败时返回SOCKET_ERROR

    listen函数

    #include <winsock2.h>
    int listen(SOCKET s, int backlog);
    

    成功时返回0,失败时返回SOCKET_ERROR

    accept函数

    #include <winsock2.h>
    SOCKET accept(SOCKET s, struct sockaddr * addr, int *addrlen);
    

    成功时返回套接字句柄,失败时返回INVALID_SOCKET

    connect函数

    #include <winsock2.h>
    int connect(SOCKET s, const struct sockaddr * name, int namelen);
    

    成功时返回0,失败时返回SOCKET_ERROR

    closesocket函数

    #include <winsock2.h>
    int closesocket(SOCKET s);
    

    成功时返回0,失败时返回SOCKET_ERROR

    send函数

    #include <winsock2.h>
    int send(SOCKET s, const char *buf, int len, int flags);
    

    成功时返回传输字节数,失败时返回SOCKET_ERROR
    - s: 表示数据传输对象连接的套接字句柄
    - buf: 保存带传输数据的缓冲地址值
    - len: 要传输的字节数
    - flags: 传输数据时用到的多种选项信息

    recv函数

    #include <winsock2.h>
    int recv(SOCKET s, const char *buf, int len, int flags);
    

    成功时返回接收的字节数(收到EOF时为0),失败时返回SOCKET_ERROR
    - s: 表示数据传输对象连接的套接字句柄
    - buf: 保存接收数据的缓冲地址值
    - len: 能够接收的最大字节数
    - flags: 接收数据时用到的多种选项信息

    server.cpp

    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <WinSock2.h>
    using namespace std;
    
    void ErrorHandling(string message);
    
    int main(int argc, char ** argv) {
        WSADATA wsaData;
        SOCKET hServSock, hClntSock;
        SOCKADDR_IN servAddr, clntSock;
    
        char message[] = "hello, world";
        if (argc != 2) {
            cout << "Usage: " << argv[0] << " <port>" << endl;
            exit(1);
        }
    
        if (WSAStartup(MAKEWORD(2, 2), &wsaData) == INVALID_SOCKET)
            ErrorHandling("WSAStartup() error");
    
        hServSock = socket(PF_INET, SOCK_STREAM, 0);
        if (hServSock == SOCKET_ERROR)
            ErrorHandling("socket() error");
    
        memset(&servAddr, 0, sizeof(servAddr));
        servAddr.sin_family = AF_INET;
        servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servAddr.sin_port = htons(atoi(argv[1]));
    
        if (bind(hServSock, (SOCKADDR *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) {
            closesocket(hServSock);
            ErrorHandling("bind() error");
        }
    
        if (listen(hServSock, 5) == SOCKET_ERROR) {
            closesocket(hServSock);
            ErrorHandling("listen() error");
        }
    
        int szClntSock = sizeof(clntSock);
        hClntSock = accept(hServSock, (SOCKADDR *)&clntSock, &szClntSock);
        if (hClntSock == INVALID_SOCKET) {
            closesocket(hServSock);
            ErrorHandling("accept() error");
        }
    
        send(hClntSock, message, sizeof(message), 0);
    
        closesocket(hServSock);
        closesocket(hClntSock);
        WSACleanup();
        return 0;
    }
    
    void ErrorHandling(string message) {
        WSACleanup();
        cerr << message << endl;
        exit(1);
    }
    

    client.cpp

    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <WinSock2.h>
    using namespace std;
    
    void ErrorHandling(string message);
    
    int main(int argc, char ** argv) {
        WSADATA wsaData;
        SOCKET hSocket;
        SOCKADDR_IN servAddr;
    
        char message[30];
        int strLen;
        if (argc != 3) {
            cout << "Usage: " << argv[0] << "<IP> <port>" << endl;
            exit(1);
        }
    
        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
            ErrorHandling("WSAStartup() error");
    
        hSocket = socket(PF_INET, SOCK_STREAM, 0);
        if (hSocket == INVALID_SOCKET)
            ErrorHandling("socket() error");
    
        memset(&servAddr, 0, sizeof(servAddr));
        servAddr.sin_family = AF_INET;
        servAddr.sin_addr.s_addr = inet_addr(argv[1]);
        servAddr.sin_port = htons(atoi(argv[2]));
    
        if (connect(hSocket, (SOCKADDR *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) {
            closesocket(hSocket);
            ErrorHandling("connect() error");
        }
    
        strLen = recv(hSocket, message, sizeof(message) - 1, 0);
        if (strLen == -1) {
            closesocket(hSocket);
            ErrorHandling("recv() error");
        }
    
        cout << "Message from server: " << message << endl;
    
        closesocket(hSocket);
        WSACleanup();
        return 0;
    }
    
    void ErrorHandling(string message) {
        WSACleanup();
        cerr << message << endl;
        exit(1);
    }
    

    运行结果

    客户端

    服务端

  • 相关阅读:
    java连接sqlserver2008报错 java.sql.SQLException: 对象名 '表名' 无效.
    hibernate中增加annotation @后不提示信息【转】
    java.io.IOException: Could not find resource SqlMapConfig.xml
    制作Lightbox效果
    myeclipse 启动卡住的解决办法
    SVN使用教程
    js基础关系运算符
    mysql怎样更改密码和用户名
    js实现点击按钮传值
    记一次Tomcat运行失败记录
  • 原文地址:https://www.cnblogs.com/wiklvrain/p/8179319.html
Copyright © 2011-2022 走看看