先举个例子来说明下套接字
地区a的区号为123,b地区的区号为321,a地区的电话号码66219677要给b地区的电话号码55768444打电话。
对应为
Ip为192.168.1.1 端口号为2000的进程 要和Ip为 192.168.1.2 端口号为3000的进程通信。
不知道这样比喻行不?
一般啊,同一个IP下的进程端口号不会重复的,就如你的电话号码一样。
socket (套接字),用于描述IP地址和端口,是一个通信链的句柄,当然描述还有协议,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
我们打电话之前,双方必须各自拥有一台电话机,同样,进行socket通信,双方需要有各自的socket,socket实质上提供了进程通信的端点。
socket通信示意图:
代码片段
服务器端:
#include <Winsock2.h>
#include <stdio.h>
#pragma comment(lib,"WS2_32.LIB")
#define Port 3000
#define MaxSize 1024
void main()
{
//加载套接字
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested=MAKEWORD(2,2);
err =WSAStartup(wVersionRequested,&wsaData);
if(err!=0)
{
printf("WinSock DLL版本有问题");
return;
}
if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
{
WSACleanup();
return;
}
//创建监听的套接字
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
//把U_LONG的主机字节顺序转换为TCP/IP网络字节顺序
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY)
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(Port);
//绑定套接字
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
//将套接字设置为监听模式,准备接受用户请求
listen(sockSrv,5);
SOCKADDR_INaddrClient;
int len=sizeof(SOCKADDR);
printf("%sn","Welcome,the Host is running!nWating for someone comesin!");
while (1)
{
//等待用户请求到来
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
charsendBuf[MaxSize];
sprintf(sendBuf,"Welcome to the Host,%s.",inet_ntoa(addrClient.sin_addr));
//发送数据
send(sockConn,sendBuf,MaxSize,0);
//接收数据
char revBuf[MaxSize];
char name[20] = {0};
int flag = 1;
while(recv(sockConn,revBuf,MaxSize,0) != -1)
{
//打印接受数据
if(flag == 1)
{
strcpy(name, revBuf);
printf("%s comes in!n",name);
flag = 2;
}
else
{
printf("%s:%sn",name, revBuf);
}
}
//关闭套接字
closesocket(sockConn);
}
}
客户端:
#include <Winsock2.h>
#include <stdio.h>
#pragma comment(lib,"WS2_32.LIB")
#define Port 3000
#define MaxSize 1024
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested=MAKEWORD(2,2);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!=0)
{
printf("WinSock DLL版本有问题");
return;
}
if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
{
WSACleanup();
return;
}
//创建套接字
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//把U_LONG的主机字节顺序转换为TCP/IP网络字节顺序
//127.0.0.1 回路地址
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(Port);
//向服务器发送请求
if(connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR))== -1)
{
printf("连接失败!输入回车结束程序!n");
getchar();
return;
}
//接受数据
charrecBuf[MaxSize];
recv(sockClient,recBuf,MaxSize,0);
printf("%sn",recBuf);
//输入name
printf("Input your Name:n");
charname[20] = {0};
gets(name);
//发送数据
send(sockClient,name,strlen(name)+1,0);
while(1)
{
gets(recBuf);
send(sockClient,recBuf,strlen(recBuf)+1,0);
}
//关闭套接字
closesocket(sockClient);
getchar();
WSACleanup();
}