正文

WinSock C/S入门实例2009-03-11 22:30:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/xman/41429.html

分享到:

   套接字的本质是通信过程中所要使用的一些缓冲区及一些相关的数据结构。

下面通过WSAWinSock API)构建最基本的C/S通信程序。

1.服务器创建监听套接字,并为它关联一个本地地址(IP和端口Port),然后进入监听状态准备接受客户的连接请求。为了接受客户的连接请求,服务器必须调用accept函数。服务器端每接收到一个客户端连接就新建一个套接字负责与该客户会话。

2.客户端创建套接字后即可调用connect函数去试图连接服务器监听套接字。当服务器端的accept函数返回后,connect函数也返回。此时客户方使用socket函数创建的套接字clientSocket,服务器方使用accept返回的套接字serverSocket,双方就可以通信了。

3.WinSock示例程序:

   (1)服务器端程序serverDemo.cpp

#include <stdio.h>

#include <WINSOCK.H>

#pragma comment(lib, "WSOCK32.LIB")  // wsock32.dll

// #include <WINSOCK2.H>

// #pragma comment(lib, "WS2_32.LIB") // ws2_32.dll

 

int main(int argc, char* argv[])

{

     // 初始化WS2_32.DLL

     WSADATA wsaData;

     WORD sockVersion = MAKEWORD(1, 0); // v2.0

     WSAStartup(sockVersion, &wsaData); // DLL装载 

     // 创建监听套接字

     SOCKET listenSocket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

     if(listenSocket == INVALID_SOCKET)

     {

         printf("Error #%d in socket() \n", WSAGetLastError());

         WSACleanup(); // DLL卸载

         return 1;

     }

     // 填充sockaddr_in结构

     sockaddr_in sin;

     sin.sin_family = AF_INET; // 地址家族

     sin.sin_port = htons(8888); // port

     sin.sin_addr.S_un.S_addr = INADDR_ANY; // ip地址

     // 绑定这个套接字到一个本地地址

     if(bind(listenSocket, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)

     {

         printf("Error #%d in bind() \n", WSAGetLastError());

         WSACleanup();//DLL卸载

         return 1;

     }

     // 进入监听模式,其中参数二backdog为监听队列中允许保持的尚未处理的最大连接数量

     if(listen(listenSocket, 2) == SOCKET_ERROR)

     {

         printf("Error #%d in listen() \n", WSAGetLastError());

         WSACleanup(); // DLL卸载

         return 1;

     }

     // 循环接收客户的连接请求

     sockaddr_in remoteAddr;

     int nAddrLen = sizeof(remoteAddr);

     SOCKET serverSocket;

     char szMsg[] = "Message from the server! \r\n";

     while(TRUE)

     {

         // 每接收到一个连接,新建一个会话socket

         serverSocket = accept(listenSocket, (SOCKADDR*)&remoteAddr, &nAddrLen);

         if(serverSocket == SOCKET_ERROR)

         {

              printf("Error #%d in accept() \n", WSAGetLastError());

              continue;

         }

         // 关闭监听套接字

         printf("接收到一个链接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));

         // 向客户端发送数据

         send(serverSocket, szMsg, strlen(szMsg), 0);

         // 关闭与客户端的会话socket

         closesocket(serverSocket);

     }

     // 关闭监听套接字

     closesocket(listenSocket);

     // 释放WS2_32

     WSACleanup(); // DLL卸载

     return 0;

}

   (2)客户端程序clientDemo.cpp

#include <stdio.h>

#include <WINSOCK.H>

#pragma comment(lib, "WSOCK32.LIB")  // wsock32.dll

// #include <WINSOCK2.H>

// #pragma comment(lib, "WS2_32.LIB") // ws2_32.dll

 

int main(int argc, char* argv[])

{

     // 初始化WS2_32.DLL

     WSADATA wsaData;

     WORD sockVersion=MAKEWORD(1, 0); // v2.0

     WSAStartup(sockVersion, &wsaData); // DLL装载

     // 创建套接字

     SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

     if(clientSocket == INVALID_SOCKET)

     {

         printf("Error #%d in socket() \n", WSAGetLastError());

         WSACleanup(); // DLL卸载

         return 1;

     }

     // 填充sockaddr_in结构

     sockaddr_in servAddr;

     servAddr.sin_family = AF_INET;

     servAddr.sin_port = htons(8888);

     servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // 或内网、公网IP,这里为本机测试

     if(connect(clientSocket, (sockaddr*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)

     {

         printf("Error #%d in socket() \n", WSAGetLastError());

         WSACleanup(); // DLL卸载

         return 1;

     }

 

     char buff[256]; // 接收数据

     int nRecv=::recv(clientSocket,buff,256,0);

     if(nRecv>0)

     {

         buff[nRecv]='\0';

         printf("接受到数据:%s",buff);

     }

     closesocket(clientSocket);

     WSACleanup(); // DLL卸载

     return 0;

}

阅读(4957) | 评论(7)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册