基于TCP协议的SOCKET通信
服务器代码
#include<WinSock2.h>//使用WinSocket库中的函数
#include<stdio.h>//使用C语言标准输入输出函数
#pragma comment(lib,"ws2_32.lib")//需要加上这个链接库不然WSAStartup报错
void main()
{
WORD wVersionRequested;//保存版本号
WSADATA wsaData;//保存加载版本的库信息
int err;
wVersionRequested=MAKEWORD(1,1);//生成版本号,如果版本是2.1则MAKEWORD(2,1);一个WORD占16位,第一参数是低八位,第二个参数是高八位,第八位是主版本,高八位是﹣版本,对于版本是2.1来说2是主版本,1是副版本号
err=WSAStartup(wVersionRequested,&wsaData);//加载套接字库,进行版本协商,如果没有wVersionRequested所指的版本,就找相近的,wsaData中wVersion存储要使用的版本号,wHeighVersion存储最高版本号
if (err!=0)//加载失败
{
return;
}
if (LOBYTE(wsaData.wVersion)!=1||
HIBYTE(wsaData.wVersion!=1))//加载版本和请求版本不一致
{
WSACleanup();
return;
}
//以上套接字版本加载完成
//开始创建套接字
SOCKET socketser=socket(AF_INET,SOCK_STREAM,0);//第一个参数是通信区域,Windows Sockets只只支持网际域所以必须是AF_INET,
//第二个参数指定产生流式套接字还是数据报套接字,TCP使用流式套接字SOCK_STREAM,UDP使用SOCK_DGRAM
//第三个参是与特定的地址家族相关的协议,设置成0时自动选择一个合适的协议。
SOCKADDR_IN addrser;//指定套接字的本地地址信息,包括IP和端口号等
addrser.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//设置可连接客户端的IP,设置INADDR_ANY表示任何客户端都可以连接,htonl()作用是将u_long从主机字节序转换为网络字节序,
addrser.sin_family=AF_INET;
addrser.sin_port=htons(6000);//设置服务器程序端口号,端口号大于1024,htons()函数是将u_short从主机字节序转换为网络字节序。
//绑定字节序
bind(socketser,(SOCKADDR*)&addrser,sizeof(SOCKADDR));//把套接字绑定在端口上,
//设置套接字为监听模式,准备接收客户端请求
listen(socketser,5);//第二个参数是等待连接队列最大长度。
SOCKADDR_IN addrcli;//用于存储客户端套接字地址信息
int len=sizeof(SOCKADDR);
while (1)
{
SOCKET socketcli=accept(socketser,(SOCKADDR*)&addrcli,&len);//返回客户端socket用来通讯,获取客户端套接字地址信息
char sendbuf[100];
sprintf(sendbuf,"welcome %s to service",inet_ntoa(addrcli.sin_addr));//格式化要发送的数据;
send(socketcli,sendbuf,strlen(sendbuf)+1,0);
char recvbuf[100];
recv(socketcli,recvbuf,100,0);
printf("%s\n",recvbuf);
closesocket(socketcli);
}
}
客户端代码
#include <WinSock2.h>
#include <stdio.h>
#pragma comment (lib,"ws2_32.lib")
void main()
{
WORD wVersionRequested=MAKEWORD(1,1);
WSADATA wsaData;
int err=WSAStartup(wVersionRequested,&wsaData);
if (err!=0)
{
return;
}
if (LOBYTE(wVersionRequested)!=1||
HIBYTE(wVersionRequested)!=1)
{
WSACleanup();
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0); //三个参数分别表示:地址族,流还是数据报类型,协议(0表示由系统选)
SOCKADDR_IN addrser;//指定套接字的本地地址信息,包括IP和端口号等
addrser.sin_addr.S_un.S_addr=inet_addr("172.18.40.21");//inet_addr将点分十进制地址转换为一个无符号整形表示形式,127.0.0.1是回送地址,指本地机,一般用来测试使用。
addrser.sin_family=AF_INET;
addrser.sin_port=htons(6000);//设置服务器程序端口号,端口号大于1024,htons()函数是将u_short从主机字节序转换为网络字节序。
connect(sockClient,(SOCKADDR*)&addrser,sizeof(SOCKADDR));
char recvBuf[100];
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
//测试发送
send(sockClient,"Client",strlen("Client")+1,0);
closesocket(sockClient);//关闭套接字
WSACleanup();//清理套接字dll
system("pause");
}
基于UDP协议的SOCKET通信
服务器
//基于UDP协议
#include<WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
void main()
{
WORD wVersionRequested=MAKEWORD(1,1);
WSADATA wsaData;
int err=WSAStartup(wVersionRequested,&wsaData);
if (err!=0)
{
return;
}
if (LOBYTE(wsaData.wVersion)!=1||
HIBYTE(wsaData.wVersion)!=1)
{
WSACleanup();
return;
}
SOCKET socketser=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrin;
addrin.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrin.sin_family=AF_INET;
addrin.sin_port=htons(6000);
bind(socketser,(SOCKADDR*)&addrin,sizeof(SOCKADDR));
char recvbuf[100];
char sendbuf[100];
char tempbuf[100];
SOCKADDR_IN addrcli;
int len=sizeof(addrcli);
while (1)
{
//等待接收数据
recvfrom(socketser,recvbuf,100,0,(SOCKADDR*)&addrcli,&len);
if (recvbuf[0]=='q')
{
sendto(socketser,"q",strlen("q")+1,0,(SOCKADDR*)&addrcli,len);
printf("chat end!\n");
break;
}
sprintf(tempbuf,"%s say:%s",inet_ntoa(addrcli.sin_addr),recvbuf);
printf("%s\n",tempbuf);
printf("Please input data:\n");
gets(sendbuf);
sendto(socketser,sendbuf,strlen(sendbuf)+1,0,(SOCKADDR*)&addrcli,len);
}
closesocket(socketser);
WSACleanup();
}
客户端
//基于UDP协议
#include<WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
void main()
{
WORD wVersionRequested=MAKEWORD(1,1);
WSADATA wsaData;
int err=WSAStartup(wVersionRequested,&wsaData);
if (err!=0)
{
return;
}
if (LOBYTE(wsaData.wVersion)!=1||
HIBYTE(wsaData.wVersion)!=1)
{
WSACleanup();
return;
}
SOCKET socketser=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrin;
addrin.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrin.sin_family=AF_INET;
addrin.sin_port=htons(6000);
char recvbuf[100];
char sendbuf[100];
char tempbuf[100];
int len=sizeof(SOCKADDR);
while (1)
{
//等待接收数据
printf("Please input data:\n");
gets(sendbuf);
sendto(socketser,sendbuf,strlen(sendbuf)+1,0,(SOCKADDR*)&addrin,len);
recvfrom(socketser,recvbuf,100,0,(SOCKADDR*)&addrin,&len);
if (recvbuf[0]=='q')
{
sendto(socketser,"q",strlen("q")+1,0,(SOCKADDR*)&addrin,len);
printf("chat end!\n");
break;
}
sprintf(tempbuf,"%s say:%s",inet_ntoa(addrin.sin_addr),recvbuf);
printf("%s\n",tempbuf);
}
closesocket(socketser);
WSACleanup();
}