TCP/IP和网络通信(TCP协议编程)

对于客户端Client来说,建立模型的步骤:

1、装入并初始化相关dll库:

if(WSAStartup(0x101,&lpWSAData)!=0){
   MessageBox(NULL,"装入并初始化DLL库失败",NULL,MB_OK);
  }

 

2、创建套接字:

 if((hSocket=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET){
  WSAGetLastError();
  MessageBox(NULL,"创建套接字失败",NULL,MB_OK);
  return FALSE;
 }

注意其中if语句中的判断顺序,先有socket()函数的赋值到hSocket中,再有hSocket==INVALID_SOCKET,注意括号的使用,否则总是得到hSocket=INVALID_SOCKET;

3、设置套接字的工作模式:

以上的创建的套接字默认情况下实在阻塞模式下工作的,为了适应windows程序工作的特点(是以消息机制来进行一系列的相关处理),要将其设置为非阻塞的工作模式:

 WSAAsyncSelect(hSocket,hWnd,WM_SOCKET,FD_CONNECT|FD_READ|FD_CLOSE|FD_WRITE);

其中WM_SOCKET是自定义消息,当调用完这个函数后,此消息便会和以hWnd为句柄的窗口绑定,当发生相应事件时,便一此消息的低双字节的lParam来指定通知码(FD_CONNET,FD_CLOSE或FD_WEITE);

4、连接到服务器: 

int i=connect(hSocket,(struct sockaddr *)&stSin,sizeof(struct sockaddr));//将套接字绑定到IP地址和端口

其中结构变量stSin是一个sockaddr_in类型的结构体变量: 

stSin.sin_addr.s_addr=inet_addr(szBuffers);//指定IP地址,其中inet_addr()函数将小数点分隔的IP地址字符串转换为32位二进制表示的IP地址(网络字节顺序)
 stSin.sin_family=AF_INET;  //指定地址格式
 stSin.sin_port= htons(TCP_PORT);//指定端口号,htons()函数将但前主机字节顺序排列的数据转换成按网络顺序排列的数据:

 

注意此时当发生这个连接动作后,服务器端的窗口程序将会接收到FD_ACCEPT的通知码,

(到这里也就顺便写到服务器端的模型建立:

1、也是装入并初始化相关dll库;

2、创建“监听套接字”hSocket

3、设置工作模式为非阻塞模式:

 WSAAsyncSelect(hSocket,hWnd,WM_SOCKET,FD_ACCEPT|FD_READ|FD_CLOSE);

4、将新的套接字与自身的IP地址和端口绑定:

 int result=bind(hSocket,(struct sockaddr *)&stSin,sizeof(stSin));

5、监听这个套接字: 

if(listen(hSocket,5)==SOCKET_ERROR)
   MessageBox(NULL,"监听失败",NULL,MB_OK);


 stSin.sin_addr.s_addr=dwIpAddr;
 stSin.sin_family=AF_INET;
 u_short ax=htons(TCP_PORT);//
 stSin.sin_port= ax;
 int i=connect(hSocket,(struct sockaddr *)&stSin,sizeof(struct sockaddr));
 int i=connect(hSocket,(struct sockaddr *)&stSin,sizeof(struct sockaddr));
当服务器端监听到有客户端发送了连接请求,则在监听套接字的作用下,服务器端的消息机制发生FD_ACCEPT的通知码,来接收客户端的请求:

   if((hNewSocket=accept(wParam,0,0))==INVALID_SOCKET){
    MessageBox(NULL,"接受客户端连接请求失败",NULL,MB_OK);
    break;
   }

注意此时返回的套接字不是之前的那个“监听套接字”了,这个套接字是和客户端相连的,而和客户端进行通信而使用的recv和send都是针对此套接字;

 

5、向服务其端发送消息:

send(hSocket,szBuffer,strlen,0);

此时服务器端将发生FD_READ的通知码,并可调用recv()函数获得客户端的文本内容:

 recv(_hSocket,szReadBuffer,sizeof(szReadBuffer),NULL);

此时服务器端可以以自己的文本格式向客户端发送文本消息:

send(hSocket,szBuffer,strlen,0);

注意:其中_hSocket就是客户端与服务器端相连时所用到的套接字,在FD_READ的wParam变量中便保存着此值。

 

6、获得有服务器端发送过来的文本请求:

同服务器端相同,在FD_READ通知码中调用recv()接收服务器端的文本格式内容‘

7、相关收尾工作,套接字的关闭,相关dll库的释放:

closesocket(hSocket);  

WSACleanup();

  WSACleanup();

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值