socket编程笔记

对于socket的用途,大家都对此很熟悉了。socket的编程总体分为服务端的编程和客户端的编程。类型我们常用的有TCP、UDP两种类型。


服务端的编程步骤:

1.初始化socket库。
2.绑定本机地址和端口。(服务端特有)
3.监听端口,等待客户端连接。
4.当有客户端连接,进行处理,但后继续监听或者结束程序。
5.退出程序,关闭socket,终止对socket库的使用。


1、这里我采用的MFC框架,首先在StdAfx.h头文件添加socket头文件和lib文件

#include "winsock2.h"
#pragma comment(lib,"ws2_32.lib")

2、初始化socket库。这里主要的工作就是定义了socket的版本,并将信息返回到wsadata结构体中

	WSADATA wsd;
	int ret=WSAStartup(MAKEWORD(2,2),&wsd);
	if (ret!=0)
	{
		return FALSE;
	}
	if (HIBYTE(wsd.wVersion)!=2||LOBYTE(wsd.wVersion)!=2)
	{
		AfxMessageBox("初始化Socket失败!");
		WSACleanup();
		return FALSE;
	}

3、创建socket。在创建socket的时候,第一个参数定义了协议域,AF_IET表示采用IPV4(32位)与端口号(16位)的组合;第二个参数是socket类型,sock_stream流式指的是TCP、sock_dgram指的是UDP;第三个参数是协议类型常用协议IPPROTO_TCP、IPPROTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议*/,我们可以填写0这样就可以自适应。

	//创建
	MySocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (MySocket==INVALID_SOCKET)
	{
		int iError=WSAGetLastError();
		CString strMsg;
		strMsg.Format("Failed socket(),Error Code is %d\n",iError);
		AfxMessageBox(strMsg);
		return ;
	}

4、设置服务端信息。我们用到了sockaddr_in这个结构体,需要关注的三个参数,第一个是IP地址,也就是要服务器要绑定的IP地址,可以自己指定也可以设置成这样。saddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //定义IP地址;第二个参数是协议类型,更上面创建的时候对应;第三个就是端口号了。

    //设置服务器信息
	sockaddr_in ServerAddr;

	CString localIP;	    //获取本地IP地址
	char hostname[MAX_PATH] = {0};
	gethostname(hostname,MAX_PATH);
	hostent* ptent = gethostbyname(hostname);
	if (ptent)
	{
		localIP = inet_ntoa(*(in_addr*)ptent->h_addr_list[0]);
	}

	ServerAddr.sin_addr.S_un.S_addr=inet_addr(localIP.GetBuffer(0));
	ServerAddr.sin_family=AF_INET;
	ServerAddr.sin_port=htons(4600);//1024 ~ 49151:普通用户注册的端口号

5、绑定。第一个参数是服务器端的socket,第二个参数存储了服务器的一些信息上面定义好的。

	//绑定
	if (bind(MySocket,(SOCKADDR *)&ServerAddr,sizeof(SOCKADDR))==SOCKET_ERROR)
	{
		int iError=WSAGetLastError();
		CString strMsg;
		strMsg.Format("Failed Bind,Error Code is %d\n",iError);
		AppendText(strMsg);
	}

6、监听客户端的连接。第一个参数的服务器的socket,第二个参数是可以连接的客户端最大个数。开始,我一直不太理解第二个参数,认为是连接一个客户端后的参数,经过我测试证明,确实是可以连接客户端的最大个数。

	//监听客户端连接
	if(listen(MySocket,2)==SOCKET_ERROR)
	{
		int iError=WSAGetLastError();
		CString strMsg;
		strMsg.Format("Failed listen,Error Code is %d\n",iError);
		AppendText(strMsg);
	}


7、等待客户端的连接。如果有多个客户端同时连接,在此处可以开辟多个线程去处理。一个线程对应于一个客户端,accept()函数,第一个参数为Server端socket,第二个为SOCKADDR结构体。如果执行成功,则会返回客户端的socket和存有客户端socket信息的结构体

	//中断等待连接
    SOCKADDR_IN ClientAddr;
	int len=sizeof(sockaddr);
	pDlg->ClientSocket=accept(pDlg->MySocket,(SOCKADDR *)&ClientAddr,&len);
	if (pDlg->ClientSocket==INVALID_SOCKET)
	{
		int iError=WSAGetLastError();
		CString strMsg;
		strMsg.Format("Failed accept,Error Code is %d\n",iError);
		pDlg->AppendText(strMsg);
	}    

8、发送数据。send函数第一个参数客户端socket,第二个参数发送的数据,返回发送成功的字符个数。这里需要注意的是发送的时候,需要加1。把字符串最后的'\0'发送过去。

	char SendBuf[1024];
	sprintf(SendBuf,"%s",str);
	if(send(ClientSocket,SendBuf,strlen(SendBuf)+1,0)==SOCKET_ERROR)
	{
		int iError=WSAGetLastError();
		CString strMsg;
		strMsg.Format("Failed send,Error Code is %d\n",iError);
		AppendText(strMsg);
	}

9、接收数据。recv函数,第一个参数为客户端socket,返回的是接收的字符个数。如果,接收失败,则关闭客户端socket

		num=recv(pDlg->ClientSocket,RecBuf,1024,0);
		if (num>=0)
		{
			RecBuf[num]='\0';
			CString str;
			str.Format("收到:%s\r\n",RecBuf);
			pDlg->AppendText(str);
		}
		else
		{
			int iError=WSAGetLastError();
			CString strMsg;
			strMsg.Format("Failed recv,Error Code is %d\n",iError);			
		    pDlg->AppendText(strMsg);
			closesocket(pDlg->ClientSocket);

以上就是服务端的程序。










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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值