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

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

#inclde <winsock2.h>

SOCKET socket(int af, int type, int protocol);
// 成功返回套接字句柄,否则INVALID_SOCKET
int bind(SOCKET s, const struct sockaddr *name, int namelen);
// 分配IP和端口号
// 成功返回0,否则SOCKET_ERROR
int listen(SOCKET s,int backlog);
// 使得套接字可接受客户端连接
// 成功返回0,否则SOCKET_ERROR
SOCKET accept(SOCKET s, struct sockaddr *addr, int *addrlen);
// 受理客户端连接
// 成功返回套接字句柄,否则INVALID_SOCKET
int connect(SOCKET s, const struct sockaddr *addr, int namelen);
// 从客户端发送连接请求
// 成功返回0,否则SOCKET_ERROR
int closesocket(SOCKET s);
// 关闭套接字的函数
// 成功返回0,否则SOCKET_ERROR

虽然返回值不太一样,但是函数名差不多吧。

Windows中的文件句柄和套接字句柄

Windows中通过系统调用函数创建文件会返回句柄(handle),句柄其实相当于Linux中的文件描述符。

创建基于Windows的服务器端和客户端

服务端示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

void error_handling(const 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 <port> \n", argv[0]);
        exit(1);
    }
    if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0)//初始化
        error_handling("WSAStartup() error");
    hServSock = socket(PF_INET,SOCK_STREAM, 0);//创建套接字
    if(hServSock == INVALID_SOCKET)
    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]));
	//分配IP和端口
    if (bind(hServSock, (SOCKADDR *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) {
        error_handling("bind() error");
    }
	//使得该套接字成为服务器端的套接字
    if (listen(hServSock, 5) == SOCKET_ERROR) {
        error_handling("listen() error");
    }

    szClntAddr = sizeof(clntAddr);
  	//接受客户端连接请求
    hClntSock = accept(hServSock, (SOCKADDR *)&clntAddr, &szClntAddr);
    if (hClntSock == INVALID_SOCKET)
        error_handling("accept() error");
	//传输数据
    send(hClntSock, message, sizeof(message), 0);
    closesocket(hClntSock);
    closesocket(hServSock);
    WSACleanup();//注销套接字库
    return 0;
}

void error_handling(const char* message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

客户端示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

void error_handling(const 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 <IP> <port> \n", argv[0]);
        exit(1);
    }
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        error_handling("WSAStartup() error");
    hSocket = socket(PF_INET, SOCK_STREAM, 0);
    if (hSocket == INVALID_SOCKET)
        memset(&servAddr, 0, sizeof(servAddr));
    servAddr.sin_family = AF_INET;
    servAddr.sin_addr.s_addr = inet_addr(argv[1]);//此处需要到项目中在属性里的C/C++下属的常规里设置SDL检查为否,否则会报错。
    servAddr.sin_port = htons(atoi(argv[2]));

    if (connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) {
        error_handling("connect() error");
    }

    strLen = recv(hSocket, message, sizeof(message) - 1, 0);
    if (strLen == -1)
        error_handling("read() error");
    printf("Messagee from server: %s \n", message);
    closesocket(hSocket);
    WSACleanup();
    return 0;
}

void error_handling(const char* message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}
基于Windows的I/O函数

Linux中的套接字是文件,因此可以共用文件I/O函数readwrite。但是Windows中不同,它严格区分文件I/O套接字I/O

#include <winsock2.h>
int send(SOCKET s, const char * buf, int len, int flags);
//成功返回传输字节数,否则SOCKET_ERROR
int recv(SOCKET s, const char * buf, int len, int flags);
//成功返回接受的字节数(收到EOF为0),否则SOCKET_ERROR
// s ---- 数据接收对象连接的套接字句柄值
// buf -- 要传输或保存数据的缓冲地址值
// len -- 要传输的字节数和能接受的最大的字节数
// flags -- 选项信息

此函数与write相比只是多出来flags,其实Linux中也有send和recv他们同属于BSD套接字。

使用read和write只是为了说明Linux中的套接字是文件。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值