本文以windows socket 进行讲解, 开发环境VS2010,测试平台 windows 7
众所周知TCP(Transmission Control Protocol )是一种面向连接的、可靠的、基于字节流的通信协议。而开发TCP socket应用程序是一件比较简单的事情。下面就用一个比较简单的demo 讲解开发的过程。
该程序分为客户端和服务器端,客户端主要是向服务器端发送数据,服务器端主要是对于接收的数据进行显示。
TCP服务器端和客户端的主要流程:
服务器端:1 创建套接字 2 绑定 3 监听 4 接受连接 5 收发数据 6 关闭
客户端: 1 创建套接字 2 连接 3 收发数据 4 关闭
实现中用到的主要函数及
服务器: 1 WSAStartup() 2 socket() 3 bind() 4 listen() 5 accept() 6 recv() 7 closesocket() 8 WSACleanup()
客户端: 1 WSAStartup() 2 socket() 3 connect() 4 send() 5 closesocket() 6 WSACleanup()
下面是server 和 client 的实现代码,运行的时候首先启动server,然后再启动client, 则在server部分打印出“hello world” 。
Server.cpp 源码
#include "stdafx.h"
#define BUF_SZIE 64
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char* argv[])
{
WSADATA wsd;
/*初始化套结字动态库*/
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("WSAStartup failed!\n");
return 1;
}
/*创建套接字*/
SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(INVALID_SOCKET == sServer)
{
printf("socket failed!\n");
WSACleanup();
return -1;
}
/*服务器套接字地址*/
SOCKADDR_IN addrServ;
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(4999);
addrServ.sin_addr.s_addr = INADDR_ANY;
/*绑定套接字*/
int retVal = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));
if (SOCKET_ERROR == retVal)
{
closesocket(sServer);
WSACleanup();
return -1;
}
/*开始监听*/
retVal = listen(sServer, 1);
if(SOCKET_ERROR == retVal)
{
closesocket(sServer);
WSACleanup();
return -1;
}
/*接受客户端请求*/
sockaddr_in addrClient;
int addrClientlen = sizeof(addrClient);
SOCKET sClient = accept(sServer,(sockaddr FAR*)&addrClient, &addrClientlen);
if(INVALID_SOCKET == sClient)
{
closesocket(sServer);
WSACleanup();
return -1;
}
/*接收客户端数据*/
char buf[BUF_SZIE];
ZeroMemory(buf, BUF_SZIE);
retVal = recv(sClient, buf, BUF_SZIE, 0);
if (SOCKET_ERROR == retVal)
{
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;
}
printf("%s\n", buf);
/*退出*/
closesocket(sServer);
closesocket(sClient);
WSACleanup();
getchar();
return 0;
}
Client.cpp 源码
#include "stdafx.h"
#define BUF_SZIE 64
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char* argv[])
{
WSADATA wsd;
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("WSAStartup failed!\n");
return -1;
}
/*创建套接字*/
SOCKET sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(INVALID_SOCKET == sHost)
{
WSACleanup();
return -1;
}
/*设置服务器地址*/
SOCKADDR_IN servAddr;
servAddr.sin_family =AF_INET;
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servAddr.sin_port = htons((short)4999);
int nServAddlen = sizeof(servAddr);
/*连接服务器*/
int retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));
if(SOCKET_ERROR == retVal)
{
closesocket(sHost);
WSACleanup();
return -1;
}
/*向服务器发送数据*/
char buf[BUF_SZIE];
ZeroMemory(buf, BUF_SZIE);
strcpy(buf, "Hello world");
retVal = send(sHost, buf, strlen(buf), 0);
if (SOCKET_ERROR == retVal)
{
closesocket(sHost);
WSACleanup();
return -1;
}
/*退出*/
closesocket(sHost);
WSACleanup();
getchar();
return 0;
}
PS : 想多说一句,如果一直无法实现通信,不妨换个端口试试~~~
我弄了好久。。。。才发现那个端口被占用了。。。。额。。。。╮(╯▽╰)╭