码迷,mamicode.com
首页 > Windows程序 > 详细

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

时间:2017-07-22 16:59:13      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:bre   字节顺序   img   down   客户   var   size   缓冲区   winsock   

在日常生活中,绝大部分人使用的机器通常是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 10

int 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

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

标签:bre   字节顺序   img   down   客户   var   size   缓冲区   winsock   

原文地址:http://www.cnblogs.com/wzjhoutai/p/7221387.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!