第四章 基本TCP套接字编程:
#include <sys/socket.h>
int socket(int family, int type, int protocol);
family:
AF_INET, AF_INET6, AF_LOCAL(AF_UNIX), AF_ROUTE, AF_KEY
type:
SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW
protocol:
IPPROTO_TCP, IPPROTO_UDP, IPPROTO_SCTP, 0(default)
error return -1
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr * servaddr, socklen_t addrlen);
success return 0, error return -1
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr * myaddr, socklen_t addrlen);
success return 0, error return -1
server:
IPV4:
struct sockaddr_in servaddr;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
IPV6:
struct sockaddr_in6 servaddr;
servaddr.sin6_addr = in6addr_any;
#include <sys/socket.h>
int listen(int sockfd, int backlog);
success return 0, error return -1
convert active-socket to passive-socket
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr * cliaddr, socklen_t * addrlen);
error return -1
sockfd should be a passive-socket(listened-socket)
#include <unistd.h>
pid_t fork(void);
error return -1
#include <unistd.h>
int execl(const char * pathname, const char * arg0, ... /* (char *)0 */);
int execv(const char * pathname, char * const argv[]);
int execle(const char * pathname, const char * arg0, ...
/* (char *)0, char * const envp[] */);
int execve(const char * pathname, char * const argv[], char * const envp[]);
int execlp(const char * filename, const char * arg0, ... /* (char *)0 */);
int execvp(const char * filename, char * const argv[]);
success no return, error return -1
#include <unistd.h>
int close(int sockfd);
success return 0, error return -1
#include <sys/socket.h>
int getsockname(int sockfd, struct sockaddr * localaddr, socklen_t * addrlen);
int getpeername(int sockfd, struct sockaddr * peeraddr, socklen_t * addrlen);
success return 0, error return -1
示例:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
void
Listen(int fd, int backlog)
{
char * ptr;
/* can override 2nd argument with environment variable */
if ((ptr = getenv("LISTENQ")) != NULL) {
backlog = atoi(ptr);
}
if (listen(fd, backlog) < 0) {
printf("listen error %s\n", strerror(errno));
exit(1);
}
}
#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define LISTENQ 5
#define MAXLINE 1024
int
main(int argc, char **argv)
{
int listenfd;
int connfd;
socklen_t len;
struct sockaddr_in servaddr;
struct sockaddr_in cliaddr;
char buff[MAXLINE];
time_t ticks;
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("socket error %s\n", strerror(errno));
exit(1);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(13); /* daytime server */
if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
printf("bind error %s\n", strerror(errno));
exit(1);
}
if (listen(listenfd, LISTENQ) == -1) {
printf("listen error\n");
exit(1);
}
for ( ; ; ) {
len = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &len);
if (connfd == -1) {
printf("accept error %s\n", strerror(errno));
exit(1);
}
if (inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)) == NULL) {
printf("inet_ntop error %s\n", strerror(errno));
exit(1);
}
printf("connection from %s, port %d\n", buff, ntohs(cliaddr.sin_port));
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
len = strlen(buff);
if (write(connfd, buff, len) != len) {
printf("write error %s\n", strerror(errno));
exit(1);
}
if (close(connfd) == -1) {
printf("close error %s\n", strerror(errno));
exit(1);
}
}
}
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define MAXLINE 1024
int
main(int argc, char **argv)
{
int sockfd;
int n;
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr;
if (argc != 2) {
printf("usage: a.out <IPaddress>\n");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("socket error %s\n", strerror(errno));
exit(1);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13); /* daytime server */
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
printf("inet_pton error for %s: %s\n", argv[1], strerror(errno));
exit(1);
}
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
printf("connect error %s\n", strerror(errno));
exit(1);
}
while ((n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = 0; /* null terminate */
if (fputs(recvline, stdout) == EOF) {
printf("fputs error %s\n", strerror(errno));
exit(1);
}
}
if (n < 0) {
printf("read error\n %s\n", strerror(errno));
exit(1);
}
exit(0);
}
#include <sys/socket.h>
int
sockfd_to_family(int sockfd)
{
struct sockaddr_storage ss;
socklen_t len;
len = sizeof(ss);
if (getsockname(sockfd, (struct sockaddr *)&ss, &len) < 0) {
return(-1);
}
return(ss.ss_family);
}