网上很多文章对于Socket的来龙去脉有如教科书一般的精准。但是涉及具体编程技术就往往被VC等集成开发环境所毒害了,把Windows SDK、Socket、多线程、DLL以及编译链接等等技术搅合在一起煮成一锅夹生饭。
1. Socket的机制是什么?
2. 用C/C++写Socket需要什么头文件、库文件、DLL,它们可以由谁提供,安装后一般处于系统的哪个文件夹内?
3. 编写Socket程序需要的编程基础是什么?
4. Socket库内最重要的几个函数和数据类型是什么?
5. 两个最简单的例子程序;
6. 一个贴近应用的稍微复杂的Socket应用程序。
对于目前使用最广泛的Windows Socket2.0版本,所需的一些文件如下(以安装了VC6为例说明其物理位置):
(1) 头文件winsock2.h,通常处于C:"Program Files"Microsoft Visual Studio"VC98"INCLUDE;查看该头文件可知其中又包含了windows.h和pshpack4.h头文件,因此在windows中的一些常用API都可以使用;
(2) 库文件Ws2_32.lib,通常处于C:"Program Files"Microsoft Visual Studio"VC98"Lib;
服务器:
1. Socket的机制是什么?
2. 用C/C++写Socket需要什么头文件、库文件、DLL,它们可以由谁提供,安装后一般处于系统的哪个文件夹内?
3. 编写Socket程序需要的编程基础是什么?
4. Socket库内最重要的几个函数和数据类型是什么?
5. 两个最简单的例子程序;
6. 一个贴近应用的稍微复杂的Socket应用程序。
一.Socket机制
Socket(套接字)是BSD提供的网络应用编程界面(API),Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。现在它已经是网络编程中的标准。
Socket是一种特殊的进程间通信方式,不同机器上的进程都可以使用这种方式进行通信,网络中的数据传输是一种I/O操作。Socket也是一种文件描述符,它代表了一个通信管道的一个端点。read,write,close操作可应用于Socket描述符。在socket类型的文件描述符上,可以完成建立连接,数据传输等操作。常用的Socket类型有两种:
流式Socket-SOCK_STREAM,提供面向连接的Socket
数据报式Socket-SOCK_DGRAM,提供面向无连接的Socket
二.所需的头文件、库文件和DLL
对于目前使用最广泛的Windows Socket2.0版本,所需的一些文件如下(以安装了VC6为例说明其物理位置):
(1) 头文件winsock2.h,通常处于C:"Program Files"Microsoft Visual Studio"VC98"INCLUDE;查看该头文件可知其中又包含了windows.h和pshpack4.h头文件,因此在windows中的一些常用API都可以使用;
(2) 库文件Ws2_32.lib,通常处于C:"Program Files"Microsoft Visual Studio"VC98"Lib;
(3) DLL文件Ws2_32.dll,通常处于C:"WINDOWS"system32,这个是可以猜到的
三 实例
服务器:
test_socket_server.cpp
#include <stdio.h>
#include <WinSock2.h>
#include <inaddr.h>
#include <Windows.h>
void ServerSocket()
{
//初始化WSA
WORD sockVersion = MAKEWORD(2,2);
WSADATA wsaData;
if(WSAStartup(sockVersion, &wsaData)!=0)
{
return ;
}
//创建套接字
SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(slisten == INVALID_SOCKET)
{
printf("socket error !");
return ;
}
//绑定IP和端口
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(8888);
sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if(bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf("bind error !");
}
//开始监听
if(listen(slisten, 5) == SOCKET_ERROR)
{
printf("listen error !");
return ;
}
//循环接收数据
SOCKET sClient;
sockaddr_in remoteAddr;
int nAddrlen = sizeof(remoteAddr);
char revData[255];
printf("等待连接...\n");
sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);
while (true)
{
if(sClient == INVALID_SOCKET)
{
printf("accept error !");
continue;
}
//printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));
//接收数据
printf("接受数据:\n");
int ret = recv(sClient, revData, 255, 0);
if(ret > 0)
{
revData[ret] = 0x00;
printf(revData);
printf("\n");
}
//发送数据
char * sendData = "你好,TCP客户端!\n";
send(sClient, sendData, strlen(sendData), 0);
}
closesocket(sClient);
closesocket(slisten);
WSACleanup();
}
int main(int argc, char* argv[])
{
//服务器端代码
ServerSocket();
return 0;
}
客户端:
test_socket_client.cpp
#include <stdio.h>
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
using namespace std;
#define IP_ADDRESS "127.0.0.1"
void ClientSocket()
{
WSADATA Ws;
SOCKET clientSocket;
struct sockaddr_in serverAddr;
int Ret = 0;
int AddrLen = 0;
char SendBuffer[MAX_PATH];
char recvData[255];
//Init Windows Socket
if ( WSAStartup(MAKEWORD(2,2), &Ws) != 0 )
{
cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
return ;
}
//Create Socket
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( clientSocket == INVALID_SOCKET )
{
cout<<"Create Socket Failed::"<<GetLastError()<<endl;
return ;
}
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
serverAddr.sin_port = htons(8888);
Ret = connect(clientSocket,(struct sockaddr*)&serverAddr, sizeof(serverAddr));
if ( Ret == SOCKET_ERROR )
{
cout<<"Connect Error::"<<GetLastError()<<endl;
return ;
}
else
{
cout<<"连接成功!"<<endl;
}
while ( true )
{
cin.getline(SendBuffer, sizeof(SendBuffer));
Ret = send(clientSocket, SendBuffer, (int)strlen(SendBuffer), 0);
if ( Ret == SOCKET_ERROR )
{
cout<<"Send Info Error::"<<GetLastError()<<endl;
break;
}
int read =recv(clientSocket,recvData,255, 0);
if(read > 0)
{
recvData[read] = 0x00;
printf(recvData);
printf("\n");
}
}
closesocket(clientSocket);
WSACleanup();
}
int main(int argc, char* argv[])
{
//客户端代码
ClientSocket();
system("pause");
return 0;
}