Windows socket网络编程

来源:互联网 发布:js如何存map 编辑:程序博客网 时间:2024/05/19 04:02

一、客户机/服务器模式

客户机/服务器模式在操作过程中采取的是主动请求的方式。

首先  服务器方要先启动,并根据请求提供相应的服务:

1、打开一个通信通道并告知本地主机,他愿意在某一地址和端口上接收客户请求。

2、等待客户请求到达该端口。

3、接收到重复服务请求,处理该请求并发送应答信号。接收到冰法服务请求,要激活一个新的进程(或线程)来处理这个客户请求。新进程(或线程)处理此客户请求,并不需要对其它请求作出应答。服务完成后,关闭此进程与客户的通信链路,并终止。

4、返回第二步,等待另一客户请求。

5、关闭服务器。

客户方:

1、打开一个通信通道,并连接到服务器所在主机的特定端口。

2、向服务器发服务请求报文,等待并接收应答;继续提出请求。

3、请求接收后关闭通信通道并终止。

二、基于socket的网络编程

1、基于TCP(面向连接)的socket编程

【1】加载套接字库;【2】进行套接字的版本协商

  WORD wVersionRequested;
  WSADATA wsaData;
  int err;
  wVersionRequested=MAKEWORD(1, 1);
  err=WSAStartup(wVersionRequested, &wsaData);
  if (err != 0)
  {
       return;
  }
  if (LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1)
  {
      WSACleanup();
      return;
 }

(1)服务器端程序

<1>创建套接字(socket)。

SOCKET sockSrv=socket(AF_INET, SOCK_STREAM, 0);

<2>将套接字绑定到一个本地地址和端口上(bind)。

SOCKADDR_IN addrSrv;//本地地址结构体变量

addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(6000);

 

bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

<3>将套接字设为监听模式,准备接收请求(listen)。

listen(sockSrv, 5);

<4>等待客户请求道来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。

SOCKADDR_IN addrClient;

int len=sizeof(SOCKADDR);

SOCKET sockConn=accept(sockSrv, (SOCKADDR*)&addrClient, &len);

<5>用返回的套接字和客户端进行通信(send/recv)。

char sendBuf[100];

send(sockConn, sendBuf, strlen(sendBuf)+1, 0);

char recvBuf[100];

recv(sockConn, recvBuf, 100, 0);

<6>返回,等待另一客户请求。

while(1)服务器程序一直运行。

<7>关闭套接字。

closesocket(sockConn);

(2)客户端程序

【1】加载套接字库;【2】进行套接字的版本协商

  WORD wVersionRequested;
  WSADATA wsaData;
  int err;
  wVersionRequested=MAKEWORD(1, 1);
  err=WSAStartup(wVersionRequested, &wsaData);
  if (err != 0)
  {
       return;
  }
  if (LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1)
  {
      WSACleanup();
      return;
 }

<1>创建套接字。

SOCKET sockClient=socket(AF_INET, SOCK_STREAM, 0);

<2>向服务器发出连接请求(connect)。

SOCKADDR_IN addrSrv;

addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(6000);

 

connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

<3>和服务器端进行通信(send/recv)。

char sendBuf[1000];

gets(sendBuf);

send(sockClient, sendBuf, strlen(sendBuf)+1, 0);

char recvBuf[100];

recv(sockClient, recvBuf, 100, 0);

<4>关闭套接字。

closesocket(sockClient);

 

WSACleanup();

2、基于UDP(面向无连接)的socket编程

(1)服务器端(接收端)程序

【1】加载套接字库;【2】进行套接字的版本协商

  WORD wVersionRequested;
  WSADATA wsaData;
  int err;
  wVersionRequested=MAKEWORD(1, 1);
  err=WSAStartup(wVersionRequested, &wsaData);
  if (err != 0)
  {
       return;
  }
  if (LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1)
  {
      WSACleanup();
      return;
 }

<1>创建套接字(socket)。

SOCKET sockSrv=socket(AF_INET, SOCK_DGRAM, 0);

<2>将套接字绑定到一个本地地址和端口上(bind)。

SOCKADDR_IN addrSrv;
 addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
 addrSrv.sin_family=AF_INET;
 addrSrv.sin_port=htons(6000);

 bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

<3>等待接收数据(recvfrom)。

 SOCKADDR_IN addrClient;
 int len=sizeof(SOCKADDR);
 char recvBuf[100];

 recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR*)&addrClient, &len);

<4>关闭套接字。

 closesocket(sockSrv);

 WSACleanup();

(2)客户端(发送端)程序

【1】加载套接字库;【2】进行套接字的版本协商

  WORD wVersionRequested;
  WSADATA wsaData;
  int err;
  wVersionRequested=MAKEWORD(1, 1);
  err=WSAStartup(wVersionRequested, &wsaData);
  if (err != 0)
  {
       return;
  }
  if (LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1)
  {
      WSACleanup();
      return;
 }

<1>创建套接字(socket)。

SOCKET sockClient=socket(AF_INET, SOCK_DGRAM, 0);

<2>向服务器发送数据(sendto)。

SOCKADDR_IN addrSrv;
 addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
 addrSrv.sin_family=AF_INET;
 addrSrv.sin_port=htons(6000);

 sendto(sockClient, "hello", strlen("hello")+1, 0,(SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

<3>关闭套接字。

closesocket(sockClient);

 WSACleanup();

 

0 0