您的位置:首页 > 理论基础 > 计算机网络

利用windows sockets实现TCP通讯示例程序

2012-08-21 02:02 369 查看
参考《精通Windows Sockets网络开发--基于Visual C++实现》

源代码下载链接

该程序由客户端和服务器端组成,实现的功能是客户端向服务器发送“MyTcp”字符串,服务器接收到该字符串,并显示出来。

客户端发送字符串后退出,服务器显示字符串后退出。

服务器实现,也即当前的TcpExample

1、 新建console程序TcpExample。A simple Application,

添加库文件ws2_32.lib为2.2版,1.1版socket为wsock32.lib,



#include <stdio.h>
#include <WINSOCK2.H>
#define BUF_SIZE 64          //缓冲区大小
char buf[BUF_SIZE];           //接收数据缓冲区
SOCKET sClient;


2、 WSAStartUp()初始化套接字动态库

WSADATA wsd;	//WSADATA变量

int retVal;		//返回值
if (WSAStartup(MAKEWORD(2,2),&wsd) != 0)
{
printf("WSAStartup 失败!\n");
return 1;
}

3、 socket()创建套接字

       //创建套接字

//创建套接字
SOCKET sServer;	//服务器套接字
sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (INVALID_SOCKET == sServer)
{
printf("创建套接字失败!\n");
WSACleanup();//释放套接字资源
return -1;
}

4、 绑定套接字

//首先定义服务地址
SOCKADDR_IN addrServ;
//服务器套接字地址
addrServ.sin_family=AF_INET;
addrServ.sin_port=htons(4999);
/*    addrServ.sin_addr.S_addr=INADDR_ANY;
addrServ.sin_addr.S_addr=INADDR_ANY;
原书错误见winsock2.h,in_addr只有一个联合体类型的S_un成员变量
*    struct in_addr {
union {
struct{ u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct{ u_short s_w1,s_w2; } S_un_w;
u_longS_addr;
} S_un;
*/
addrServ.sin_addr.S_un.S_addr=INADDR_ANY;
//绑定套接字
retVal=bind(sServer,(LPSOCKADDR)&addrServ,sizeof(SOCKADDR_IN));
if(SOCKET_ERROR == retVal)
{
printf("绑定失败!\n");
closesocket(sServer);//关闭套接字
WSACleanup();//释放套接字资源
return-1;
}


5、 监听

//开始监听,设置等待接受连接的队列长度为1
retVal=listen(sServer,1);
if(SOCKET_ERROR == retVal)
{
printf("监听失败!\n");
closesocket(sServer);
WSACleanup();
return-1;
}


6、 接受客户端连接

      

//accept函数处于阻塞状态,直到接受了一个客户端请求。当该函数返回时,新建一个套接字,同时返回该客户端的地址
//如果调用失败,则返回INVALID_SOCKET
sockaddr_inaddrClient;
intaddrClientlen =sizeof(addrClient);
sClient=accept(sServer,(sockaddrFAR*)&addrClient,&addrClientlen);
if(INVALID_SOCKET == sClient)
{
printf("接受客户端连接失败!\n");
closesocket(sServer);
WSACleanup();
return-1;
}


7、 接受客户端数据

//接收并显示数据
//调用recv() 函数接收客户端发送的数据。在调用该函数前首先调用ZeroMemory()函数将接收数据缓冲区设置为0,最后调用printf显示数据
charbuf[128];
intBUF_SIZE=128;
ZeroMemory(buf,BUF_SIZE);
retVal=recv(sClient,buf,BUF_SIZE,0);
if(SOCKET_ERROR ==retVal)
{
printf("接收数据失败!\n");
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return-1;
}
printf("%s\n",buf);//输出数据


8、 退出

     

closesocket(sServer);
closesocket(sClient);
WSACleanup();


实现客户端

客户端主要功能是连接服务器,向服务器发送“MyTcp”字符串。客户端的实现包括

初始化套接字动态库、创建套接字、连接服务器、发送数据和退出。

1、 console程序TcpClient,选中Add to current workspace,A simple Application ,



2、 #include <stdio.h>,添加库文件

3、 定义全局变量

#include <WINSOCK2.H>
#define BUF_SIZE 64          //缓冲区大小
WSADATA wsd;                  //WSADATA变量
SOCKET sHost;                   //服务器套接字
SOCKADDR_IN servAddr;   //服务器地址
char buf[BUF_SIZE];           //接收数据缓冲区
int retval;                            //返回值


4、 初始化套接字动态库

//初始化套接字动态库
if(WSAStartup(MAKEWORD(2,2),(LPWSADATA)&wsd)!=0)
{
printf("WSAStartup失败!\n");
return-1;
}


5、 创建套接字

//创建套接字
sHost=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(INVALID_SOCKET == sHost)
{
printf("创建套接字失败!\n");
WSACleanup();
return-1;
}


6、 连接服务器

设置IP地址为127.0.0.1,服务器端口为4999.调用connect() 函数连接服务器。

//设置服务器地址
servAddr.sin_family=AF_INET;
servAddr.sin_port=htons((short)4999);
servAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
intnServAddlen=sizeof(servAddr);
//连接服务器
retval=connect(sHost,(LPSOCKADDR)&servAddr,sizeof(servAddr));
if(SOCKET_ERROR == retval)
{
printf("连接服务器失败! \n");
closesocket(sHost);
WSACleanup();
}


7、 发送数据

      

//首先利用ZeroMemory设置发送数据缓冲区为0
ZeroMemory(buf,BUF_SIZE);
strcpy(buf,"MyTcp");
retval=send(sHost,buf,strlen(buf),0);
if(SOCKET_ERROR == retval)
{
printf("向服务器发送数据失败! \n");
closesocket(sHost);
WSACleanup();
return-1;
}


 

8、 退出

      

      

closesocket(sHost);
WSACleanup();


 

先运行TcpExample,再运行TcpClient。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息