BSD Socket API
客户端代码:
socket()
创建一个新的确定类型的套接字,类型用一个整型数值标识(文件描述符),并为它分配系统资源。bind()
一般用于服务器端,将一个套接字与一个套接字地址结构相关联,比如,一个指定的本地端口和IP地址。listen()
用于服务器端,使一个绑定的TCP套接字进入监听状态。connect()
用于客户端,为一个套接字分配一个自由的本地端口号。 如果是TCP套接字的话,它会试图获得一个新的TCP连接。accept()
用于服务器端。 它接受一个从远端客户端发出的创建一个新的TCP连接的接入请求,创建一个新的套接字,与该连接相应的套接字地址相关联。send()
和recv()
,或者write()
和read()
,或者recvfrom()
和sendto()
, 用于往/从远程套接字发送和接受数据。close()
用于系统释放分配给一个套接字的资源。 如果是TCP,连接会被中断。gethostbyname()
和gethostbyaddr()
用于解析主机名和地址。select()
用于修整有如下情况的套接字列表: 准备读,准备写或者是有错误。poll()
用于检查套接字的状态。 套接字可以被测试,看是否可以写入、读取或是有错误。getsockopt()
用于查询指定的套接字一个特定的套接字选项的当前值。setsockopt()
用于为指定的套接字设定一个特定的套接字选项。
服务器端代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#define BUF_SIZE 1024
void thread_socket_function(void *args) {
int fd = (int) args;
int rdcnt, wrcnt;
char buf[BUF_SIZE];
printf("sockfd:%d\n", fd);
while (1) {
rdcnt = read(fd, buf, BUF_SIZE);
if (rdcnt == -1) {
perror("read");
} else {
if (!strcmp(buf, "bye")) {
break;
} else {
printf("recv:%s\n", buf);
strcpy(buf, "receive success!");
wrcnt = write(fd, buf, strlen(buf) + 1);
if (wrcnt == -1) {
perror("write");
}
}
}
}
close(fd);
pthread_exit(NULL);
}
int main(int argc, char **argv) {
int server_sockfd;
struct sockaddr_in server_addr;
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (server_sockfd == -1) {
perror("socket");
return -1;
}
memset(&server_addr, 0, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_port = 8888;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
bind(server_sockfd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in));
listen(server_sockfd, 5);
for (;;) {
int client_sockfd;
int client_len = sizeof(struct sockaddr_in);
struct sockaddr_in client_addr;
pthread_t thread;
int ret;
client_sockfd = accept(server_sockfd, (struct sockaddr*) &client_addr,
(socklen_t *__restrict) &client_len);
ret = pthread_create(&thread, NULL, (void *) &thread_socket_function,
(void *) client_sockfd);
if (ret) {
perror("pthread_create");
continue;
}
}
pthread_exit(NULL);
return 0;
}
客户端代码:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define BUF_SIZE 1024
int main(int argc, char **argv) {
int client_sockfd;
struct sockaddr_in address;
int ret;
char buf[BUF_SIZE];
int client_len = sizeof(struct sockaddr_in);
client_sockfd = socket(AF_INET, SOCK_STREAM, 0);
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_port = 8888;
ret = connect(client_sockfd, (struct sockaddr *) &address, client_len);
if (ret == -1) {
perror("connect");
return -1;
}
while (1) {
scanf("%s", buf);
write(client_sockfd, buf, strlen(buf) + 1);
if (!strcmp(buf, "bye")) {
break;
}
read(client_sockfd, buf, BUF_SIZE);
printf("recev:%s\n", buf);
}
close(client_sockfd);
return 0;
}