#define __SOCKADDR_COMMON(sa_prefix) \
sa_family_t sa_prefix##family
#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int))
/* Structure describing an Internet socket address. */
struct sockaddr_in
{
__SOCKADDR_COMMON (sin_);
in_port_t sin_port; /* Port number. */
struct in_addr sin_addr; /* Internet address. */
/* Pad to size of `struct sockaddr'. */
unsigned char sin_zero[sizeof (struct sockaddr) -
__SOCKADDR_COMMON_SIZE -
sizeof (in_port_t) -
sizeof (struct in_addr)];
};
socket函数
包含头文件<sys/socket.h>
功能:创建一个套接字用于通信
原型
int socket(int domain, int type, int protocol);
参数
domain :指定通信协议族(protocol family)
type:指定socket类型,流式套接字SOCK_STREAM,数据报套接字SOCK_DGRAM,原始套接字SOCK_RAW
protocol :协议类型
返回值:成功返回非负整数, 它与文件描述符类似,我们把它称为套接口描述字,简称套接字。失败返回-1
bind函数
包含头文件<sys/socket.h>
功能:绑定一个本地地址到套接字
原型
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数
sockfd:socket函数返回的套接字
addr:要绑定的地址
addrlen:地址长度
返回值:成功返回0,失败返回-1
listen函数
一般来说,listen函数应该在调用socket和bind函数之后,调用函数accept之前调用。
对于给定的监听套接口,内核要维护两个队列:
1、已由客户发出并到达服务器,服务器正在等待完成相应的TCP三路握手过程
2、已完成连接的队列
accept函数
包含头文件<sys/socket.h>
功能:从已完成连接队列返回第一个连接,如果已完成连接队列为空,则阻塞。
原型
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数
sockfd:服务器套接字
addr:将返回对等方的套接字地址
addrlen:返回对等方的套接字地址长度
返回值:成功返回非负整数,失败返回-1
connect函数
包含头文件<sys/socket.h>
功能:建立一个连接至addr所指定的套接字
原型
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数
sockfd:未连接套接字
addr:要连接的套接字地址
addrlen:第二个参数addr长度
返回值:成功返回0,失败返回-1
client.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
int main(void)
{
int sockfd = 0;
sockfd = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in srvaddr;
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(8001);
srvaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //127.0.0.1
//srvaddr.sin_addr.s_addr = inet_addr(INADDR_ANY); //绑定本机的任意一个地址
if (connect(sockfd, (struct sockaddr*) (&srvaddr), sizeof(srvaddr)) < 0) {
perror("fun socket\n");
exit(0);
}
printf("connect success\n");
printf("socketfd = %d\n",sockfd);
return 0;
}
server.c
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>
int main()
{
//int socket(int domain, int type, int protocol);
int socketfd = socket(AF_INET, SOCK_STREAM, 0);
printf("socketfd = %d\n", socketfd);
if (socketfd == -1) {
perror("creat socket error");
return -1;
}
// man 7 ip
/*
struct sockaddr_in {
sa_family_t sin_family; // address family: AF_INET
in_port_t sin_port; //port in network byte order
struct in_addr sin_addr; //internet address
};
// Internet address.
typedef uint32_t in_addr_t;
struct in_addr {
in_addr_t s_addr;
};
*/
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8001);
//The inet_addr() function converts the Internet host address cp from IPv4 numbers-and-dots
//notation into binary data in network byte order.
server_addr.sin_addr.s_addr = INADDR_ANY; //127.0.0.1
//int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
if (bind(socketfd, (const struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) {
//error : can not assign request address
perror("bind socket error");
return -1;
}
//int listen(int sockfd, int backlog);
//this limit was a hard coded value, SOMAXCONN, with the value 128.
if (listen(socketfd, SOMAXCONN) == -1) {
perror("listen error");
return -1;
}
//The argument addr is a pointer to a sockaddr structure.
//This structure is filled in with the address of the peer socket, as known to the communications layer.
//On success, these system calls return a nonnegative integer that is a descriptor for the accepted socket.
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
struct sockaddr_in peer_addr;
socklen_t len;
int peer_fd;
if ((peer_fd = accept(socketfd, (struct sockaddr *) &peer_addr, &len)) == -1) {
perror("accept error");
return -1;
}
//char *inet_ntoa(struct in_addr in);
printf("peer id address = %s,port=%d\n", inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port));
return 0;
}