1. socket网络编程分为客户端和服务器端,客户端发送请求,服务器端进行应答;
建立连接时,服务器端绑定端口监听(bind&listen),客户端发送连接请求(connect),然后服务器端接受请求accept,至此客户端和服务器端可以收发消息。
需要注意:
1)创建socket前需要调用WSAStartup,对socket进行初始化。
2)服务器端的accept函数,第三个参数addrlen既是输出,也是输入参数,所以需要有初值sizeof(sockaddr);
accept(SOCKET s, struct sockaddr FAR * addr,int FAR * addrlen);
2. 客户端的几个接口函数:
初始化socket:
wVersionRequested = MAKEWORD( 2, 0 );
WSAStartup(wVersionRequested , &wsaData);
创建socket:
fd = socket(AF_INET,SOCK_STREAM,0);
连接服务器:
memset(&serverAddr,0,sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(800);
serverAddr.sin_addr.S_un.S_addr = inet_addr("192.168.0.22");
connfd = connect(clientfd,(sockaddr *)&serverAddr,sizeof(sockaddr));
发送消息:
send(fd,pBuf,10,0);
关闭socket:
closesocket(clientfd);
3.服务器端的几个API:
初始化socket:
wVersionRequested = MAKEWORD( 2, 0 );
WSAStartup(wVersionRequested , &wsaData);
创建socket:
fd = socket(AF_INET,SOCK_STREAM,0);
绑定端口bind():
memset(&serverAddr,0,sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(800);
serverAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
bind(serverfd,(sockaddr *)&serverAddr,sizeof(sockaddr));
监听端口listen:
listen(serverfd,1024);
connfd = connect(clientfd,(sockaddr *)&serverAddr,sizeof(sockaddr));
接受连接accept:
addrLen = sizeof(sockaddr); //需注意,addrLen是输入输入函数,必须先赋值再传入accept。
connfd = accept(serverfd,(sockaddr *)&clientAddr,&addrLen);
接收消息recv:
recv(connfd,buf,100,0); //此处socket用的是connfd.
关闭socket:
closesocket(fd);
4.客户端程序:
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib ")
int main()
{
int clientfd=0;
int connfd =0;
int ret =0;
struct sockaddr_in serverAddr;
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
if (WSAStartup(wVersionRequested , &wsaData)!=0)
{
printf("Winsock Initialization failed./n");
exit(0);
};
clientfd = socket(AF_INET,SOCK_STREAM,0);
if(clientfd <0)
{
printf("/r/ncreate socket error: %d",clientfd);
return -1;
}
else
{
printf("/r/ncreate socket success,socket: %d",clientfd);
}
memset(&serverAddr,0,sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(800);
serverAddr.sin_addr.S_un.S_addr = inet_addr("192.168.0.22");
connfd = connect(clientfd,(sockaddr *)&serverAddr,sizeof(sockaddr));
if(connfd < 0 )
{
printf("/r/nconnect socket fail,connfd: %d/r/n",connfd);
return -1;
}
else
{
printf("/r/nconnect socket success,connfd: %d",connfd);
}
//sendto(clientfd,pBuf,ucLen,(sockaddr *)&serverAddr,sizeof(sockaddr));
char pBuf[10] = "123456789";
send(clientfd,pBuf,10,0);
closesocket(clientfd);
return 0;
}
5.服务器端程序:
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib ")
int main()
{
int serverfd=0;
int connfd =0;
int ret =0;
struct sockaddr_in serverAddr;
struct sockaddr_in clientAddr;
int addrLen = 0;
char buf[100];
char ucLen;
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
if (WSAStartup(wVersionRequested , &wsaData)!=0)
{
printf("Winsock Initialization failed./n");
exit(0);
};
serverfd = socket(AF_INET,SOCK_STREAM,0);
if(serverfd <0)
{
printf("/r/ncreate socket error: %d",serverfd);
return -1;
}
else
{
printf("/r/ncreate socket success,socket: %d",serverfd);
}
memset(&serverAddr,0,sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(800);
serverAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
if(bind(serverfd,(sockaddr *)&serverAddr,sizeof(sockaddr)) < 0)
{
printf("/r/nbind socket fail,serverfd: %d/r/n",serverfd);
return -1;
}
if(listen(serverfd,1024) < 0)
{
printf("/r/nbind socket fail,serverfd: %d/r/n",serverfd);
return -1;
}
do
{
addrLen = sizeof(sockaddr);
connfd = accept(serverfd,(sockaddr *)&clientAddr,&addrLen);
if(addrLen != 0 )
{
printf("/r/naccept socket success,/n/rconnfd: %u,clientIp:%s,clientPort:%u",
connfd,(inet_ntoa)(clientAddr.sin_addr),clientAddr.sin_port);
}
recv(connfd,buf,100,0);
printf("recv data: %s",buf);
}while(1);
closesocket(serverfd);
return 0;
}
6.参考书籍:
《深入理解计算机系统》十二章:网络编程