网编(1):Linux和Windows的套接字

网友投稿 262 2022-11-18

网编(1):Linux和Windows的套接字

1 基于Linux的套接字相关函数及示例

socket函数

#include int socket(int domain, int type, int protocol);

bind函数

#include int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen);

listen 函数

#include int listen(int sockfd, int backlog);

accept函数

#include int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

第一步: 调用socket函数创建套接字。 第二步: 调用bind函数分配IP地址和端口号。 第三步: 调用listen函数转为可接收请求状态。 第四步 :调用accept函数受理连接请求。

服务器端 ( server )实例代码:

#include #include #include #include #include #include void error_handling(char *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 \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(char *message){ fputs(message, stderr); fputc('\n', stderr); exit(1);}

客户端实例代码:

#include #include #include #include #include #include void error_handling(char *message);int main(int argc, char* argv[]){ int sock; struct sockaddr_in serv_addr; char message[30]; int str_len; if(argc!=3) { printf("Usage : %s \n", argv[0]); 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) error_handling("connect() error I"); str_len = read(sock, message, sizeof(message)-1); if(str_len==-1) error_handling("read() error!"); printf("Message from server: %s \n", message); close(sock); return 0;}void error_handling(char *message){ fputs(message, stderr); fputc('\n', stderr); exit(1);}

运行:——————————

//服务器$ gcc client.c -o b.out$ ./a.out 9190//客服端$ ./b.out 192.168.1.141 9190Message from server: Hello World!

2 基于Windows的套接字相关函数及示例

添加库:

四个主要函数:

#include SOCKET socket(int af , int type, int pr otocol);#include int bind(SOCKET s, const struct sockaddr * name, int namelen);#include int listen(SOCKET s,int backlog);#include SOCKET accept(SOCKET s, struct sockaddr * addr, int * addrlen);

下列函数与Linux的 connect函数相同,调用其从客户端发送连接请求 。

#include int connect(SOCKET s, const struct sockaddr * name, int namelen);

最后这个函数在关闭套接字时调用 。 Linux中,关闭文件和套接字时都会调用close函数;而Windows中有专门用来关闭套接字的函数 。

#include int closesoc ket(SOCKET s);

Windows 中的文件句柄和套接字句柄 Linux 内部也将套接字当作文件,因 此,不管创建文件还是套接字都返回文件描述符 。 之前也通过示例介绍了文件描述符返回及编号的过程 。 Windows中通过调用系统函数创建文件时,返回”句柄" (handle ), 换言之, Windows中的句柄相当千Linux中的文件描述符 。 只不过Windows中要区分文件句柄和套接字句柄 。 虽然都称为"句柄",但不像Linux那样完全一致 。 文件句柄相关函数与套接字句柄相关函数是有区别 的 ,这一点不同于Linux文件描述符 。 既然对句柄有了一定理解,接下来再观察基于Windows的套接字相关函数 , 这将加深各位对SOCKET类型的参数和返回值的理解 。 的确!这就是为了保存套接字句柄整型值的新数据类型,它由 typede伊明定义 。 回顾socket 、 Listen和accept等套接字相关函数,则更能体会到与Linux中套接字相关函数的相似性 。 有些程序员可能会问:“既然Winsock是以UNIX 、 Linux系列的BSD套接字为原型设计的 ,为什么不照搬过来,而是存在一定差异呢?”有人认为这是微软为了防止UNIX 、 Linux服务器端直接移植到Windows而故意为之。 从网络程序移植性角度上看,这也是可以理解的 。 但我有不同意见 。 从本质上说,两种操作系统内核结构上存在巨大差异, 而依赖于操作系统的代码实现风格也不尽相同 , 连Windows程序员给变量命名的方式也不同千Linux程序员 。 从各方面考虑,保持这种差异性就显得比较自然 。 因此我个人认为, Windows套接字与BSD系列的套接字编程方式有所不同是为了保持这种自然差异性 。

服务器实例代码:————————————————————

#include #include #include void ErrorHandling(char* message);int main(int argc, char* argv[]){ WSADATA wsaData; SOCKET hServSock, hClntSock; SOCKADDR_IN servAddr, clntAddr; int szClntAddr; char message[] = "Hello World!"; if (argc = 2) { printf("Usage : %s \n", argv[0]); exit(1); } if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) ErrorHandling("WSAStartup() error!"); hServSock = socket(PF_INET, SOCK_STREAM, 0);//第一步 if (hServSock == INVALID_SOCKET) 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)//第二步 ErrorHandling("bind() error"); if (listen(hServSock, 5) == SOCKET_ERROR)//第三步 ErrorHandling("listen() error"); szClntAddr = sizeof(clntAddr); hClntSock = accept(hServSock, (SOCKADDR*)&clntAddr, &szClntAddr);//第四步 if (hClntSock == INVALID_SOCKET) ErrorHandling("accept() error"); send(hClntSock, message, sizeof(message), 0); closesocket(hClntSock); closesocket(hServSock); WSACleanup(); return 0;}void ErrorHandling(char* message){ fputs(message, stderr); fputc('\n', stderr); exit(1);}

客户端实例代码:————————————————————

#include #include #include #include void ErrorHandling(char* message);int main(int argc, char* argv[]){ WSADATA wsaData; SOCKET hSocket; SOCKADDR_IN servAddr; char message[30]; int strlen; if (argc != 3) { printf("Usage : %s \n", argv[0]); exit(1); } if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) ErrorHandling("WSAStartup() error I"); 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)//第二步 ErrorHandling("connect() error! "); strlen = recv(hSocket, message, sizeof(message) - 1, 0); if (strlen == -1) ErrorHandling("read() error! "); printf("Message from server: %s \n", message); closesocket(hSocket); WSACleanup(); return 0;}void ErrorHandling(char* message){ fputs(message, stderr); fputc('\n', stderr); exit(1);}

运行程序:

//服务器D:\> server 9190//客服端D:\> client 192.168.43.110 9190Message from server: Hello World!

基于Windows 的I/O函数

发送函数:

#include int send(SOCKET s, canst char* buf, int len, int flags);//成功时返回传输字节数,失败时返回SOCKET_ERROR。s //表示数据传输对象连接的套接字句柄值。buf //保存待传输数据的缓冲地址值。len //要传输的字节数。flags //传输数据时用到的多种选项信息。

接收函数:

#include int recv(SOCKET s, const char* buf, int len, int flags);//成功时返回传输字节数,失败时返回SOCKET_ERROR。s //表示数据传输对象连接的套接字句柄值。buf //保存待传输数据的缓冲地址值。len //要传输的字节数。flags //传输数据时用到的多种选项信息。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:龙焱能源获光智资本领投新一轮融资,龙焱能源持续发展建筑光伏一体化
下一篇:国民技术USBKEY系列安全芯片 Z8D168
相关文章

 发表评论

暂时没有评论,来抢沙发吧~