小练习:用socket实现Linux和Windows之间的通信

来源:互联网 发布:java联机游戏代码实现 编辑:程序博客网 时间:2024/05/23 12:22

在日常生活中,绝大部分人使用的机器一般是windows系统,但是对于研发人员,开发、编译等工作往往是建立在linux机器上。事实上,在服务器方面,Linux、UNIX和WindowsServer占据了市场的大部分份额;在超级计算机方面,Linux取代Unix成为了第一大操作系统。

通信是计算机和操作系统的一大任务,通过ftp、ping、ssh等方式,人们可以很方便与服务器连接。一个庞大的网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。windows系统使用的是windows socket,而linux使用的posix socket。今天结合了网上一些经典例程,写了一个简单的socket代码,实现Ubuntu(虚拟机中)和Windows的通信。

Windows平台下客户端的实现代码:

#include <stdio.h>#include <Windows.h>#pragma comment(lib, "ws2_32.lib")#define Port 5000#define IP_ADDRESS "172.30.70.95"int main(int argc, char* argv[]) // argc是命令行总的参数个数{        WSADATA s; // 用来储存调用AfxSocketInit全局函数返回的Windows Sockets初始化信息        SOCKET ClientSocket;        struct sockaddr_in ClientAddr; // 一个sockaddr_in型的结构体对象        int ret = 0;        char SendBuffer[MAX_PATH];   // Windows的MAX_PATH默认是260        // 初始化Windows Socket        // WSAStartup函数对Winsock服务的初始化        if (WSAStartup(MAKEWORD(2, 2), &s) != 0) // 通过连接两个给定的无符号参数,首个参数为低字节        {            printf("Init Windows Socket Failed! Error: %d\n", GetLastError());            getchar();            return -1;        }        while (1)        {        // 创建一个套接口        // 如果这样一个套接口用connect()与一个指定端口连接        // 则可用send()和recv()与该端口进行数据报的发送与接收        // 当会话结束后,调用closesocket()        ClientSocket = socket(AF_INET, // 只支持ARPA Internet地址格式            SOCK_STREAM, // 新套接口的类型描述            IPPROTO_TCP); // 套接口所用的协议        if (ClientSocket == INVALID_SOCKET)        {            printf("Create Socket Failed! Error: %d\n", GetLastError());            getchar();            return -1;        }        ClientAddr.sin_family = AF_INET;        ClientAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS); // 定义IP地址        ClientAddr.sin_port = htons(Port); // 将主机的无符号短整形数转换成网络字节顺序        memset(ClientAddr.sin_zero, 0X00, 8); // 函数通常为新申请的内存做初始化工作        // 连接Socket        ret = connect(ClientSocket,            (struct sockaddr*)&ClientAddr,            sizeof(ClientAddr));        if (ret == SOCKET_ERROR)        {            printf("Socket Connect Failed! Error:%d\n", GetLastError());            getchar();            return -1;        }        else        {            printf("Socket Connect Succeed!");        }        printf("Input Data: ");        while (1)        {            scanf("%s", &SendBuffer);            // 发送数据至服务器            ret = send(ClientSocket,                SendBuffer,                (int)strlen(SendBuffer), // 返回发送缓冲区数据长度                0);            if (ret == SOCKET_ERROR)            {                printf("Send Information Failed! Error:%d\n", GetLastError());                getchar();                break;            }            break;        }        // 关闭socket        closesocket(ClientSocket);        if (SendBuffer[0] == 'q') // 设定输入第一个字符为q时退出        {            printf("Quit!\n");            break;        }    }           WSACleanup();                    getchar();        return 0;}

我的linux(Ubuntu)端网络信息:

这里写图片描述

linux(Ubuntu)平台下的服务器代码:

#include <unistd.h>#include <stdio.h>#include <i386-linux-gnu/sys/socket.h>#include <netinet/in.h>#include <i386-linux-gnu/sys/types.h>#include <stdlib.h>#include <string.h>#define SERVER_PORT 5000#define LENGTH_OF_LISTEN_QUEUE 20#define BUFFER_SIZE 10int main() // (int argc, char* argv[]){    struct sockaddr_in server_addr;    int server_socket;    int opt = 1;    bzero(&server_addr, sizeof(server_addr)); // 置字节字符串前n个字节为0,包括'\0'    server_addr.sin_family = AF_INET;    server_addr.sin_addr.s_addr = htons(INADDR_ANY); // 转小端,INADDR_ANY就是指定地址为0.0.0.0的地址    server_addr.sin_port = htons(SERVER_PORT);      // 创建一个Socket    server_socket = socket(PF_INET, SOCK_STREAM, 0);    if (server_socket < 0)    {        printf("Create Socket Failed!\n");        exit(1);    }    // bind a socket    setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));    if(bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))    {        printf("Server Bind Port: %d Failed!\n", SERVER_PORT);        exit(1);    }    // 监听Socket    if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))    {        printf("Server Listen Failed!\n");        exit(1);    }          while(1)    {        struct sockaddr_in client_addr;        int client_socket;        socklen_t length;        char Buffer[BUFFER_SIZE];        // 连接客户端Socket        length = sizeof(client_addr);        client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);        if (client_socket < 0)        {            printf("Server Accept Failed!\n");            break;        }        // 从客户端接收数据        while(1)        {            bzero(Buffer, BUFFER_SIZE);            length = recv(client_socket, Buffer, BUFFER_SIZE, 0);            if (length < 0)            {                printf("Server Recieve Data Failed!\n");                break;            }                       if ('q' == Buffer[0])            {                printf("Quit!\n");                break;            }            printf("%s\n", Buffer);            break;        }        close(client_socket);    }    close(server_socket);    return 0;}

在打开客户端时,服务器端要确保已处于监听状态,否则连接失败:

这里写图片描述

打开服务器端程序如下:

这里写图片描述

数据传输成功:

这里写图片描述

这个小实验只花了很少的时间调试,且只能单向发送数据,功能单一,纯粹只是一个小练习,socket编程的调试中,主要关注程序出错时返回的错误值,从中往往能很快找出代码的漏洞。

参考链接:http://blog.csdn.net/feixiaoxing/article/details/8567162

3 0
原创粉丝点击