1.TCP和UDP的区别(面试可能会问)
2. 字节序
字节序,即字节在电脑中存放时的序列与输入(输出)时的序列是先到的在前还是后到的在前。
3. Little endian: 小端:将低序字节存储在起始地址
- Big endian:大端: 将高序字节存储在起始地址
Sockt服务器和客户端的开发思路:
开发中用到的API 解析:
1.socket:
函数原型:
int socket(int domain, int type, int protocol);
参数简析:
2.bind:
函数原型:
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数简析:
socklen_t addrlen // 第二个参数结构体的长度。
3.地址转换API:
4.listen:
int listen(int sockfd, int backlog);
参数简析:
5.accept:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数简析:
6.数据收发交互函数:
TCP:可以用read,write。也可以用send,recv :
UDP一般使用以下这俩套收发函数:
7.客户端连接:connect
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
参数简析:
搜索:
端口字节序转换API:
如何关闭端口:lsof -i:端口号 // kill-9 +pid
CLC@Embed_Learn:~$ lsof -i:6666
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
a.out 7081 CLC 3u IPv4 46787 0t0 TCP none.local:6666 (LISTEN)
a.out 7081 CLC 4u IPv4 46788 0t0 TCP none.local:6666->none.local:46068 (ESTABLISHED)
telnet 7088 CLC 3u IPv4 49247 0t0 TCP none.local:46068->none.local:6666 (ESTABLISHED)
CLC@Embed_Learn:~$ kill -9 7081
案例1:实现服务器和客户端间的聊天(跨平台,多客户)
服务器端:
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include<string.h>
int main(int argc,char **argv)
{
int s_fd;
int c_fd;
int nread;
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
pid_t pid;
memset(&s_addr,0,sizeof(struct sockaddr_in));
memset(&c_addr,0,sizeof(struct sockaddr_in));
int size=sizeof(struct sockaddr_in);
char readBuf[128];
char gmsg[128];
if(argc<3){
printf("can shu bu gou\n");
exit(-1);
}
s_fd=socket(AF_INET,SOCK_STREAM,0);
if(s_fd==-1){
perror("socket");
exit(-1);
}
s_addr.sin_family=AF_INET;
s_addr.sin_port=htons(atoi(argv[2]));
inet_aton(argv[1],&s_addr.sin_addr);
if(bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in))==-1){
perror("bind");
}
if(listen(s_fd,5)==-1){
perror("listen");
exit(-1);
}
while(1){
c_fd=accept(s_fd,(struct sockaddr *)&c_addr,&size);
if(c_fd==-1){
perror("accept");
exit(-1);
}
printf("ID:%s\n",inet_ntoa(c_addr.sin_addr));
pid=fork();
if(pid==0){
printf("fathar:pid:%d\n",getppid());
while(1){
memset(readBuf,0,sizeof(readBuf));
nread=read(c_fd,readBuf,128);
if(nread==-1){
perror("read");
}
printf("read from client:%d byte: %s\n",nread,readBuf);
memset(gmsg,0,sizeof(gmsg));
printf("input: \n");
gets(gmsg);
if(write(c_fd,gmsg,strlen(gmsg))==-1){
perror("write");
}
}
}
}
return 0;
}
客户端:
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//#include<linux/in.h>
#include <unistd.h>
#include<string.h>
int main(int argc,char **argv)
{
int c_fd;
int nread;
struct sockaddr_in c_addr;
memset(&c_addr,0,sizeof(struct sockaddr_in));
int size=sizeof(struct sockaddr_in);
char readBuf[128];
char gmsg[128];
if(argc<3){
printf("can shu bu gou\n");
exit(-1);
}
c_fd=socket(AF_INET,SOCK_STREAM,0);
if(c_fd==-1){
perror("socket");
exit(-1);
}
c_addr.sin_family=AF_INET;
c_addr.sin_port=htons(atoi(argv[2]));
inet_aton(argv[1],&c_addr.sin_addr);
if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in))==-1){
perror("connect");
exit(-1);
}
while(1){
memset(gmsg,0,sizeof(gmsg));
printf("input: \n");
gets(gmsg);
if(write(c_fd,gmsg,strlen(gmsg))==-1){
perror("write");
}
memset(readBuf,0,sizeof(readBuf));
nread=read(c_fd,readBuf,128);
if(nread==-1){
perror("read");
}
printf("read from serval:%d byte: %s\n",nread,readBuf);
}
return 0;
}