引用图片了解客户端、服务器基本架构
一、socket函数(创建一个新的socket)
1.头文件:
#include <sys/types.h>
#include <sys/socket.h>
2.函数原型:
int socket(int domain, int type, int protocol);
3.参数:
1)通信协议
AF_INET Ipv4 网络协议
AF_INET6 Ipv6 网络协议
2)通信类型
1、SOCK_STREAM 提供双向连续且可信赖的数据流, 即TCP. 支持 OOB 机制, 在所有数据传送前必须使用connect()来建立连线状态.
2、SOCK_DGRAM 使用不连续不可信赖的数据包连接
3、SOCK_SEQPACKET 提供连续可信赖的数据包连接
4、SOCK_RAW 提供原始网络协议存取
5、SOCK_RDM 提供可信赖的数据包连接
3) 一般设为零
4.返回值:成功返回socket套接字的网络标识符,失败则返回-1。
二、bind函数(绑定端口号、IP地址)
1.头文件:#include<sys/socket.h>
2.函数原型:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
3.参数:
1)网络描述符(既是socket函数创建成功的返回值)
2)第二个参数是一个指向特定协议的地址结构的指针
结构体名: sockaddr_in
头文件:#include<linux/in.h>
结构体成员1:sin_family(通信协议一般IPV4为AF_INET)。
结构体成员2:sin_ port(端口号)(需要用到主机端口号转网络传输方式函数–htons)。
结构体成员3:struct in_addr sin_addr(又是一个结构体)(配置网络IP地址)(需要用到inet_aton函数–网络的阿斯克码转网络传输方式)。
3)第三个参数是地址结构体的长度
4.返回值:成功返回0,失败返回-1,发送错误信息。
三、listen函数(监听)
1.头文件:
#include <sys/types.h>
#include <sys/socket.h>
2.函数原型:int listen(int sockfd, int backlog);
3.参数:
1)网络标识符(既是socket函数的成功调用的返回值)
2)承载量(表示最多可同时监听的数量)
4.返回值:成功返回0,失败返回-1,并且返回错误信息
四、accept函数(等待连接,运行时阻塞至客户端成功接入)
1.头文件:
#include <sys/types.h>
#include <sys/socket.h>
2.函数原型:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
3.参数:
1)网络标识符(同上)
2)结构体指针(保存连接的网络信息)
3) 结构体的长度
4.返回值:成功返回接入网络的客户端网络标识符,失败返回-1,返回错误信息。
五、connect函数(客户端接入服务器函数)
1.头文件:
#include <sys/types.h>
#include <sys/socket.h>
2.函数原型:
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
3.参数:
1)网络标识符(客户端成功调用socket函数的返回值)
2)结构体指针(保存连接的网络信息)
3) 结构体的长度
4.返回值:成功返回接入0,失败返回-1,返回错误信息。
六、 连接成功后可用read、write函数进行数据的收发,read、write函数使用见文件编程基础
七、服务器、客户端小程序代码展示
服务器代码
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
int s_fd;
int c_fd;
int n_read;
char readBuf[128];
char writeBuf[128];
int n_write;
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
memset(&s_addr, 0, sizeof(struct sockaddr_in));
memset(&c_addr, 0, sizeof(struct sockaddr_in));
// socket
s_fd = socket(AF_INET, SOCK_STREAM, 0);
if (s_fd == -1) {
perror("socket");
exit(-1);
}
// init struct sockaddr_in
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[1]));
inet_aton("192.168.81.129", &s_addr.sin_addr);
// bind
bind(s_fd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr_in));
// listen
listen(s_fd, 10);
// accept
// int c_fd = accept(s_fd,(struct sockaddr *)&c_addr,(unsigned
// *)sizeof(struct sockaddr_in));
int c_len = sizeof(struct sockaddr_in);
while (1) {
c_fd = accept(s_fd, (struct sockaddr *)&c_addr, &c_len);
// why???
if (c_fd == -1) {
perror("accept");
exit(-1);
}
printf("connected to IP: %s\n", inet_ntoa(c_addr.sin_addr));
if (fork() == 0) {
if (fork() == 0) {
while (1) {
printf("input: \n");
memset(writeBuf, 0, 128);
gets(writeBuf);
n_write = write(c_fd, writeBuf, strlen(writeBuf));
if (n_write == -1) {
perror("write");
}
}
}
while (1) {
memset(readBuf, 0, 128);
n_read = read(c_fd, readBuf, 128);
if (n_read == -1) {
perror("read");
} else {
printf("client message: %s\n", readBuf);
}
}
}
}
return 0;
}
客户端代码
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
int c_fd;
int n_read;
char readBuf[128];
char writeBuf[128];
struct sockaddr_in c_addr;
memset(&c_addr, 0, sizeof(struct sockaddr_in));
// socket
c_fd = socket(AF_INET, SOCK_STREAM, 0);
if (c_fd == -1) {
perror("socket");
exit(-1);
}
// init struct sockaddr_in
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(atoi(argv[1]));
inet_aton("192.168.81.129", &c_addr.sin_addr);
int r_con =
connect(c_fd, (struct sockaddr *)&c_addr, sizeof(struct sockaddr));
if (r_con == -1) {
perror("connect");
}
while (1) {
printf("input: \n");
memset(writeBuf,0,128);
gets(writeBuf);
write(c_fd, writeBuf, strlen(writeBuf));
if (fork() == 0) {
while (1) {
memset(readBuf,0,128);
n_read = read(c_fd, readBuf, 128);
if (n_read == -1) {
perror("read");
} else {
printf("Server Message: %s\n", readBuf);
}
}
}
}
return 0;
}