1. 程式人生 > >網路程式設計 筆記(二) 基於 Windows簡單通訊

網路程式設計 筆記(二) 基於 Windows簡單通訊

windows套接字程式設計

1、設定庫Alt+F7 ->“配置屬性”-> “聯結器” -> “輸入” -> “附加依賴項” -> “ws2_32.lib

2、標頭檔案:#include <winsock2.h>

3、Winsock的初始化
- 首先必須呼叫WSAStartup函式,設定程式中用到的Winsock版本,並初始化響應版本的庫。
- int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSData);
- 成功時返回0, 失敗時返回非零的錯誤程式碼值。
- wVersionRequested 是Winsock的版本資訊。
- lpWSData WSADATA結構體變數的地址值
- 藉助MAKEWORD巨集函式構建WORD型版本資訊,
- 如:MAKEWORD(1, 2);表示主版本為1,副版本為2,返回0x0201

4、Winsock的登出
- int WSAClenup();
- 成功時返回0, 失敗時返回SOCKET_ERROR。
- 呼叫該函式時,Winsock相關庫歸還Windows作業系統,無法再呼叫Winsock相關函式

  • server.cpp
// server.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdlib.h>
#include <WinSock2.h>

void EfforHandling(char
*message); int main(int argc, char* argv[]) { WSADATA wsaData; SOCKET hServSock, hClientSock; 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) { EfforHandling("WSAStartup() error!"); } hServSock = socket(PF_INET, SOCK_STREAM, 0); if (hServSock == INVALID_SOCKET) { EfforHandling("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) { EfforHandling("bind() error!"); } if (listen(hServSock, 5) == SOCKET_ERROR) { EfforHandling("listen() error!"); } szClntAddr = sizeof(clntAddr); hClientSock = accept(hServSock, (SOCKADDR*)&clntAddr, &szClntAddr); if (hClientSock == INVALID_SOCKET) { EfforHandling("accept() error!"); } send(hClientSock, message, sizeof(message), 0); closesocket(hClientSock); closesocket(hServSock); WSACleanup(); system("pause"); return 0; } void EfforHandling(char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); }
  • client.cpp
// client.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdlib.h>
#include <WinSock2.h>

void EfforHandling(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]);
    }

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        EfforHandling("WSAStartup() error!");
    }

    hSocket = socket(PF_INET, SOCK_STREAM, 0);
    if (hSocket == INVALID_SOCKET)
    {
        EfforHandling("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)
    {
        printf("connect() error %ld\n", WSAGetLastError());
        EfforHandling("connect() error!");
    }

    strLen = recv(hSocket, message, sizeof(message)-1, 0);
    if (strLen == -1)
    {
        EfforHandling("recv() error!");
    }
    printf("Message from server: %s \n", message);

    closesocket(hSocket);
    WSACleanup();

    system("pause");
    return 0;
}

void EfforHandling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}
  • server執行引數設定 visual studio ->PROJECT->Configuration Properties->Debuggins->Command Arguments->9018
  • client執行引數設定 visual studio ->PROJECT->Configuration Properties->Debuggins->Command Arguments->127.0.0.1 9018
  • 先執行server,再執行client

  • windows和linux對套接字的I/O操作不同

  • window對winsock的操作 int send(SOCKET s, const char *buf, int len, int flags);
    1、s 表示資料傳輸物件連線的套接字控制代碼值
    2、buf 儲存待傳輸資料的緩衝地址值
    3、len 要傳輸的位元組數
    4、flags 傳輸資料時用到的多種選項資訊
    5、成功是返回傳輸位元組數,失敗時返回SOCKET_ERROR

  • window對winsock的操作 int recv(SOCKET s, const char *buf, int len, int flags);
    1、s 表示資料接收物件連線的套接字控制代碼值
    2、buf 儲存接收資料的緩衝地址值
    3、len 能夠接收的最大位元組數
    4、flags 接收資料時用到的多種選項資訊
    5、成功是返回接收位元組數(收到EOF時為0),失敗時返回SOCKET_ERROR

  • 請不要誤認為linux中的read、write函式就是對應於Windows的send、recv函式。