网络编程入门

xiaoxiao2021-02-27  231

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>\n", 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); }

运行结果

转载请注明原文地址: https://www.6miu.com/read-12131.html

最新回复(0)