目录
Sockt服务器和客户端的开发步骤
1.socket 指定讲“汉语”(连接协议)
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
2.bind 地址准备好
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
端口号: 一般3000以下是系统一些关键端口用的,我们用户一般用5000-9000之间使用的比较多
字节序:2、字节序(全)_单片机爱好者之家的博客-CSDN博客
2.1 字节序转换API:
#include <netinet/in.h> uint16_t htons(uint16_t host16bitvalue); //返回网络字节序的值 uint32_t htonl(uint32_t host32bitvalue); //返回网络字节序的值 uint16_t ntohs(uint16_t net16bitvalue); //返回主机字节序的值 uint32_t ntohl(uint32_t net32bitvalue); //返回主机字节序的值 h代表host,n代表net,s代表short(两个字节),l代表long(4个字节), 通过上面的4个函数可以实现主机字节序和网络字节序之间的转换。 有时可以用INADDR_ANY,INADDR_ANY指定地址让操作系统自己获取
怎么查询 struct sockaddr_in:
1. cd /usr/include/ (在这一目录下查找)
2.grep "struct sockaddr_in {" * -nir (n:找出来显示行号,i:不区分大小写,r:是递归的意思)3.vi linux/in.h +184 (linux/in.h是头文件)
怎么查询 struct in_add:
struct sockaddr_in 的第三个参数也是一个结构体 struct in_addr
cd /usr/include/ (在这一目录下查找)
grep "struct in_addr {" * -nir
vi linux/in.h +56
2.2 地址转换API:
int inet_aton(const char* straddr,struct in_addr *addrp);
把字符串形式的“192.168.1.123”转为网络能识别的格式
char* inet_ntoa(struct in_addr inaddr);
把网络格式的ip地址转为字符串形式
3.listen 监听
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
4.accept 连接
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
5.数据收发
ssize_t write(int fd, const void *buf, size_t nbytes);
ssize_t read(int fd, void *buf, size_t nbytes);
函数均返回读或写的字节个数,出错则返回 -1
数据收发常用第二套API
6.客户端的connect函数
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
1.服务器代码(单个服务端)
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
int main(int argc,char **argv)
{
int s_fd;
//1.socket
s_fd = socket(AF_INET,SOCK_STREAM,0);
if(s_fd == -1){
perror("socked");
exit(-1);
}
struct sockaddr_in s_addr;
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[2]));
//s_addr.sin_addr.s_addr = argv[1]; (error)
inet_aton(argv[1],&s_addr.sin_addr); //写虚拟机linux的ip地址,用于等会连接
//2.bind
bind(s_fd, (struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
//3.listen
listen(s_fd,10);
//4.accept
int c_fd = accept(s_fd,NULL,NULL);
//5.read
//6.write
printf("connect\n");
while(1);
return 0;
}
2.服务器收发代码1.0版本(接收客户端发送)
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
//int socket(int domain, int type, int protocol);
//int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
int main()
{
int s_fd;
int n_read;
char readBuf[128];
char *msg = "I get your message";
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));
//1.socket
s_fd = socket(AF_INET,SOCK_STREAM,0);
if(s_fd == -1){
perror("socked");
exit(-1);
}
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[2]));
//s_addr.sin_addr.s_addr = "127.0.0.1"; (不是这样写的)
inet_aton(argv[1],&s_addr.sin_addr);
//2.bind
bind(s_fd, (struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
//3.listen
listen(s_fd,10);
//4.accept
int clen = sizeof(struct sockaddr_in);
int c_fd = accept(s_fd,(struct sockaddr *)&c_addr, &clen);
if(c_fd == -1){
perror("accept");
}
printf("get connect:%s\n",inet_ntoa(c_addr.sin_addr)); //inet_ntoa()函数,把网络格式的 IP 地址转为字符串形式
//5.read
n_read = read(c_fd,readBuf,128);
if(n_read == -1){
perror("read");
}else{
printf("get message: %d ,%s\n",n_read,readBuf);
}
//6.write
write(c_fd,msg,strlen(msg));
return 0;
}
2.1客户端代码
int main()
{
int c_fd;
int n_read;
char readBuf[128];
char *msg = "Message form client";
struct sockaddr_in c_addr;
memset(&c_addr,0,sizeof(struct sockaddr_in));
//1.socket
c_fd = socket(AF_INET,SOCK_STREAM,0);
if(c_fd == -1){
perror("socked");
exit(-1);
}
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(atoi(argv[2]));
//s_addr.sin_addr.s_addr = "127.0.0.1"; //(不是这样写的)
inet_aton(argv[1],&c_addr.sin_addr);
//2.connect
if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in)) == -1){
perror("connect");
exit(-1); //连接不到服务端会阻塞,出错直接跳出程序,以免搞崩代码
}
//3.send
write(c_fd,msg,128);
//4.read
n_read = read(c_fd,readBuf,128);
if(n_read == -1){
perror("read");
}else{
printf("get message from server: %d ,%s\n",n_read,readBuf);
}
return 0;
}