第一次学socket,惭愧,看了一些博客和项目代码写出来的小demo。

功能:
启动server端进程后,server端进入监听。
启动client端进程,用户输入字符串。
server端打印接收到的字符串,等待用户输入字符串,回复给client端。
client端打印接收到的字符串,demo结束。

server端代码:

#include <WinSock2.h>    //for bind()
#include <stdio.h>

/* 长度 */
#define MAX_DATA_BUF_LEN    (1024)
#define MAX_STR_IP_LEN      (24)

/* 客户端端口和服务端端口*/
#define SERVER_PORT         (12345)
#define CLIENT_PORT         (12344)

/* 远端ip字符数组 */
char strRemoteIP[MAX_STR_IP_LEN] = { 0 };

void log(const char* str) {
    printf("%s\n", str);
}

/* 初始化winsock */
int winSockInit() {
    WSADATA wsaData;
    int ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (ret != 0) {
        printf("WSAStartup failed: %d\n", ret);
        WSACleanup();
        return -1;
    }
    else {
        /* 初始化成功则打印版本 */
        printf("%s\n", wsaData.szDescription);
    }
    return 0;
}

/* 创建socket句柄,绑定到指定端口 */
int udpCreate(unsigned short port) {
    if (0 != winSockInit()) {
        return -1;
    }

    /* 创建socket:地址家族,socket类型,传输层协议 */
    int socket_handle = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (INVALID_SOCKET == socket_handle) {
        log("Invalid socket!");
        return -1;
    }

    /* 绑定端口 */
    struct sockaddr_in addr_info = { 0 };
    addr_info.sin_family = AF_INET;
    addr_info.sin_port = htons(port);
    addr_info.sin_addr.S_un.S_addr = inet_addr("0.0.0.0");
    if (-1 == bind(socket_handle, (const struct sockaddr*)&addr_info, sizeof(addr_info))) {
        log("bind error!");
        return -1;
    }

    return socket_handle;
}

/* 从socket句柄接收消息 */
int udpRecv(int handle) {
    log("waiting for msg...");

    char data_buf[MAX_DATA_BUF_LEN] = { 0 };
    struct sockaddr_in client_info = { 0 };
    int name_len = sizeof(client_info);

    /* 调用后进入阻塞 */
    int ret = recvfrom(handle, data_buf, sizeof(data_buf), 0, (struct sockaddr*)&client_info, &name_len);
    if (-1 == ret) {
        log("recv error!");
        return -1;
    }
    else {
        /* 收到消息后保存远端ip */
        char* ip_str = inet_ntoa(client_info.sin_addr);
        memcpy(strRemoteIP, ip_str, strlen(ip_str));
        printf("receive %d bytes from %s:%s\n", ret, strRemoteIP, data_buf);
    }
    return 0;
}

/* 向指定远端发送消息 */
int udpSend(int handle, const char* remoteIP, int port, char* data,int len) {
    struct sockaddr_in client_info = { 0 };
    client_info.sin_family = AF_INET;
    client_info.sin_port = htons(port);
    client_info.sin_addr.S_un.S_addr = inet_addr(remoteIP);
    int name_len = sizeof(client_info);
    int ret = sendto(handle, data, len, 0, (struct sockaddr*)&client_info, name_len);
    if (-1 != ret) {
        printf("successfully sent %d bytes.\n", ret);
    }
    else {
        return -1;
    }
    return 0;
}

int main() {
    int handle = udpCreate(SERVER_PORT);
    if (-1 == handle) {
        log("Invalid socket!");
        return -1;
    }
    udpRecv(handle);

    /* 获取输入*/
    log("say something to the client:");
    char data[MAX_DATA_BUF_LEN];
    fgets(data, MAX_DATA_BUF_LEN, stdin);

    /* 发送数据 */
    udpSend(handle, strRemoteIP, CLIENT_PORT, data,strlen(data));
}

client端代码:

#include <WinSock2.h>    //for bind()
#include <stdio.h>

/* 长度 */
#define MAX_DATA_BUF_LEN    (1024)
#define MAX_STR_IP_LEN      (24)

/* 客户端端口和服务端端口*/
#define SERVER_PORT         (12345)
#define CLIENT_PORT         (12344)

/* 远端ip字符数组 */
char strRemoteIP[MAX_STR_IP_LEN] = { 0 };

void log(const char* str) {
    printf("%s\n", str);
}

/* 初始化winsock */
int winSockInit() {
    WSADATA wsaData;
    int ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (ret != 0) {
        printf("WSAStartup failed: %d\n", ret);
        WSACleanup();
        return -1;
    }
    else {
        /* 初始化成功则打印版本 */
        printf("%s\n", wsaData.szDescription);
    }
    return 0;
}

/* 创建socket句柄,绑定到指定端口 */
int udpCreate(unsigned short port) {
    if (0 != winSockInit()) {
        return -1;
    }

    /* 创建socket:地址家族,socket类型,传输层协议 */
    int socket_handle = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (INVALID_SOCKET == socket_handle) {
        log("Invalid socket!");
        return -1;
    }

    /* 绑定端口 */
    struct sockaddr_in addr_info = { 0 };
    addr_info.sin_family = AF_INET;
    addr_info.sin_port = htons(port);
    addr_info.sin_addr.S_un.S_addr = inet_addr("0.0.0.0");
    if (-1 == bind(socket_handle, (const struct sockaddr*)&addr_info, sizeof(addr_info))) {
        log("bind error!");
        return -1;
    }

    return socket_handle;
}

/* 从socket句柄接收消息 */
int udpRecv(int handle) {
    log("waiting for msg...");

    char data_buf[MAX_DATA_BUF_LEN] = { 0 };
    struct sockaddr_in client_info = { 0 };
    int name_len = sizeof(client_info);

    /* 调用后进入阻塞 */
    int ret = recvfrom(handle, data_buf, sizeof(data_buf), 0, (struct sockaddr*)&client_info, &name_len);
    if (-1 == ret) {
        log("recv error!");
        return -1;
    }
    else {
        /* 收到消息后保存远端ip */
        char* ip_str = inet_ntoa(client_info.sin_addr);
        memcpy(strRemoteIP, ip_str, strlen(ip_str));
        printf("receive %d bytes from %s:%s\n", ret, strRemoteIP, data_buf);
    }
    return 0;
}
/* 向指定远端发送消息 */
int udpSend(int handle, const char* remoteIP, int port, char* data,int len) {
    struct sockaddr_in client_info = { 0 };
    client_info.sin_family = AF_INET;
    client_info.sin_port = htons(port);
    client_info.sin_addr.S_un.S_addr = inet_addr(remoteIP);
    int name_len = sizeof(client_info);
    int ret = sendto(handle, data, len, 0, (struct sockaddr*)&client_info, name_len);
    if (-1 != ret) {
        printf("successfully sent %d bytes.\n", ret);
    }
    else {
        return -1;
    }
    return 0;
}

int main() {

    /* 创建套接字 */
    int handle = udpCreate(CLIENT_PORT);
    if (-1 == handle) {
        log("Invalid socket!");
        return -1;
    }

    /* 获取输入*/
    log("say something to the server:");
    char data[MAX_DATA_BUF_LEN];
    fgets(data, MAX_DATA_BUF_LEN, stdin);

    /* 发送数据 */
    udpSend(handle, "127.0.0.1", SERVER_PORT, data,strlen(data));

    /* 接收数据 */
    udpRecv(handle);
}

MorpheusDong
4 声望0 粉丝