socket编程之阻塞模式

Windows下的Winsock编程有阻塞、非阻塞以及各种I/O模型。阻塞模型是最基本也是最简单的方式。Winsock有两个版本,Winsock 1和Winsock 2,两者都可以在(除wince之外的)的所有windows操作系统上运行。Wince只支持Windsock 1。当使用WINSOCK2.H时需要连接WS2_32.lib库,使用WINSOCH.H时用WSOCK32.LIB库。接下来分别介绍阻塞模式服务器端和客户端。

       在实际应用中,服务器几乎都不用阻塞模式实现,但是作为学习来说,还是一步步来,从理解阻塞模式。阻塞模式简单服务器端实现步骤如下:

1、 初始化

2、 创建socket套接字

3、 绑定套接字

4、 监听

5、 接受连接

6、 接收数据


#include "stdafx.h"
#include <windows.h>
#include <process.h>
#include <WINSOCK2.H>

#pragma comment(lib,"WS2_32.lib")

DWORD WINAPI RecData(LPVOID lparam)
{

SOCKET *psocket=(SOCKET *)lparam;

if(psocket!=NULL)

{

char rec[1024]={0};

int i=0;

//接收数据

i=recv(*psocket,rec,1024,0);

printf("%s\n",rec);

closesocket(*psocket);

}

return 0;

}

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

WSADATA wsa;

SOCKET ServSoc;

SOCKET Newconnection;

sockaddr_in SerAddr;

sockaddr_in ClientAddr;

//初始化socket版本2.2

if(0!=WSAStartup(MAKEWORD(2,2),&wsa))

return 0;

//判定版本是不是2.2,不是的话说明版本不符合要求

if(LOBYTE(wsa.wVersion)!=2||HIBYTE(wsa.wVersion)!=2)

{

//不符合要求就要释放资源,一旦WSAStartup,最后都必需要用WSACleanup

WSACleanup();

printf("%s","version is not fit\n");

return 0;

}

//创建一个套接字,用来监听客户连接

ServSoc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

if(INVALID_SOCKET==ServSoc)

{

WSACleanup();

printf("%s","Socket init failed\n");

return 0;

}

//建立一个sockaddr_in,监听端口设置为5150,地址用INADDR_ANY,当服务器有n个ip时,将指向任意空闲ip。

//在设置过程中都要将主机字节顺序转换为网络字节顺序,即htons、htonl

SerAddr.sin_family=AF_INET;

SerAddr.sin_port=htons(5150);

SerAddr.sin_addr.s_addr=htonl(INADDR_ANY);

//将监听端口和服务器地址和套接字关联起来,即绑定

if(SOCKET_ERROR==bind(ServSoc,(sockaddr *)&SerAddr,sizeof(SerAddr)))

{

closesocket(ServSoc);

WSACleanup();

printf("%s","the binding operation failed\n");

return 0;

}

int ilen=sizeof(sockaddr_in);

while(1)

{

//监听客户机连接,连接数最大为5

if(SOCKET_ERROR!=listen(ServSoc,5))

{

//接受连接,返回一个新的套接字,之后与这个连接的操作都是通过这个套接字来实现的。

//当再次对ServSoc调用accept时,又可以接受新的连接

Newconnection=accept(ServSoc,(sockaddr *)&ClientAddr,&ilen);

if(INVALID_SOCKET!=Newconnection)

{

//对刚刚的连接开启一个线程接受数据,传入的参数是新建的那个套接字

HANDLE m_hThread=(HANDLE)_beginthreadex(NULL,0,(unsigned int( __stdcall *)(void *))RecData,&Newconnection,CREATE_SUSPENDED,NULL);

if(NULL!=m_hThread)

{

ResumeThread(m_hThread);

CloseHandle(m_hThread);

}

printf("Hello World!\n");

}

}

Sleep(0);

}

//最后关闭套接字,WSACleanup释放相关资源

closesocket(ServSoc);

WSACleanup();

return 0;

}


客户端简单实现步骤如下:

1、 初始化

2、 创建socket套接字

3、 连接服务器

4、 发送数据

#include "stdafx.h"
#include <WINSOCK2.H>
#include <iostream>

#pragma comment(lib,"WS2_32.lib")

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

WSADATA wsa;

SOCKET ClientSoc;

sockaddr_in SerAddr;

//初始化socket版本2.2

if(0!=WSAStartup(MAKEWORD(2,2),&wsa))

{

printf("%s","WSAStartup operation failed\n");

return 0;

}

//创建一个套接字

ClientSoc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

if(INVALID_SOCKET==ClientSoc)

{

WSACleanup();

printf("%s","socket init failed\n");

return 0;

}

//建立一个sockaddr_in,服务器监听端口为5150,服务器ip地址192.168.1.116

//在设置过程中htons将主机字节顺序转换为网络字节顺序,inet_addr将一个点分十进制的IP转换成一个长整数型数

SerAddr.sin_family=AF_INET;

SerAddr.sin_port=htons(5150);

SerAddr.sin_addr.s_addr=inet_addr("192.168.1.116");

//连接服务器

if(SOCKET_ERROR==connect(ClientSoc,(sockaddr *)&SerAddr,sizeof(sockaddr_in)))

{

printf("%s","the connect operation failed\n");

closesocket(ClientSoc);

WSACleanup();

return 0;

}

char buf[1024]={0};

strcpy(buf,"connet server success");

int i=0;

//发送数据

i=send(ClientSoc,buf,strlen(buf),0);

printf("Hello World!\n");

//最后关闭套接字,WSACleanup释放相关资源

closesocket(ClientSoc);

WSACleanup();

std::cin>>i;

return 0;

}

结果如下:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值