网络字节顺序:TCP/IP采用16/32位高位先存格式
TCP/IP网络应用中,通信的两个进程主要采用C/S模式。
服务器要先启动,并根据请求提供相应的服务:1、打开一个通信通道订告知本地主机,它愿意在某一地址和端口上接受客户请求;2、等待客户请求到达该端口;3、接受到重复服务请求,处理该请求并发送应答信号。接收到并发服务请求,要急活一个新的进程(或线程)来处理这个客户请求。服务完成后关闭此新进程与客户的通信链路并终止;4、返回第二步,等待新的请求;5关闭服务器。
客户方:1、打开一个通信通道,并连接到无武器所在主机的特定端口;2、想服务器发送请求报文,等待并接受应答,继续提出请求。3请求结束后青碧通道并终止。
套接字类型:
1、
2、
3、
基于TCP的socket编程:
服务器端:
1、
2、
3、
4、
5、
6、
7、
客户端:
1、
2、
3、
4、
基于UDP的socket编程
服务器端:
1、
2、
3、
4、
客户端:
1、
2、
3、
具体事例讲解:
首先加载WSAStartup套接字库。
int WSAStartup(
);
加载完套接字库后需要创建套接字(socket)
SOCKET socket(
int af,//指定地址族,对与TCP/IP只能是AF_INET
int type,//指定socket类型,对与1.1版本,只支持SOCK_STREAM和SOCK_GRAM
int protocol//与特定的地址家族相关的协议,if 0,自动选择一个合适的协议
);
绑定本地地址和端口
int bind(
SOCKET s,
const struct sockaddr* name,
int namelen
);
struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
typedef struct in_addr {
union {
struct {
u_char s_b1,s_b2,s_b3,s_b4;
} S_un_b;
struct {
u_short s_w1,s_w2;
} S_un_w;
u_long S_addr;
} S_un;
} in_addr;
u_long htonl(
u_long hostlong
);// The htonl function converts a u_long from host to TCP/IP network byte order (which is big endian).
u_short htons(
u_short hostshort
);The htons function converts a u_short from host to TCP/IP network byte order (which is big-endian).
用inet_addr()函数将点分十进制的ip地址转换成u_long类型
用inet_ntoa()完成相反的转换
可以讲ip地址指定为INADDR_ANY,允许套接字想任何分配给本地机器的IP地址发送数据
绑定完套接字后需要调用listen把套接字设置为监听模式
int listen(
SOCKET s,
int backlog//等待连接队列的最大值
);
然后等待连接请求的到来。
While(1)
{
//调用accept()
};
SOCKET accept(
SOCKET s,
struct sockaddr* addr,//接受发起连接的客户端地址
int* addrlen
);
接受到客户请求后就可以发送数据了
int send(
SOCKET s,
const char* buf,
int len,
int flags
);
发送完数据后可以调用接受函数接收数据
int recv(
SOCKET s,
char* buf,
int len,
int flags
);
在运行winsocket程序要包含Winsock2.h
需要连接ws2_32.lib库文件。
下面分析客户端的程序:
首先也应建立套接字socket
对于客户端不需要绑定,直接连接服务器端。
int connect(
SOCKET s,
const struct sockaddr* name,//要建立连接的地址信息
int namelen
);
在本地机器上可以用127.0.0.1,这是一个回路地址。
最后调用closesocket()
和 WSACleanup()。
Udp的socket程序与tcp基本类似。
建立套接字socket
绑定套接字bind
用recvfrom函数接受数据
int recvfrom(
SOCKET s,
char* buf,//用来接受数据
int len,//buf长度
int flags,
struct sockaddr* from,//接收发送数据方的地址信息
int* fromlen
);
下面来看基于UDP的客户端的程序:
首先建立套接字;
这里不需要绑定,直接发送数据。
int sendto(
SOCKET s,
const char* buf,//发送的数据
int len,//数据的长度
int flags,//它的值影响发送数据的行为,一般设为0
const struct sockaddr* to,//设定目的套接字的地址信息
int tolen
);