在TCP/IP协议中,IP地址+端口号标识个唯一的一个进程,“IP地址+端口号”就是socket
在TCP协议中,建立连接需要两个进程各自有一个socket标识符,这两个socket组成的socket pair就标识着唯一的连接
相关概念介绍首先呢,我们都知道内存中的多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件的偏移也有大端和小端之分。
同理,网络数据流其实也有大端和小端之分。
网络数据流的地址这样规定:先发出的数据是低地址,后发出的数据是高地址。
TCP/IP协议规定:网络数据流应采用大端字节序,低地址高字节
创建socket套接字
#include
#include
int socket(int domain,int type, int protocol);
domain我们一般选择AF_INET,表示IPv4
type表示传输数据的类型,有字节流类型和SOCK_STREAM数据报类型SOCK_DGRAM
protocol表示创建的类型方式,我们此时设置为0
成功返回对应的文件描述符
错误返回-1
进行服务器的IP地址和端口号的绑定
#include
#include
#include
int bind(int sockfd,const struct sockaddr *addr, socklen_t addrlen);
sockfd是服务器的套接字,就是socket函数的返回值
addr是socket服务器的地址内容
addrlen是传入的协议地址的大小
成功返回0
错误返回-1
设置套接字为监听的状态
#include
#include
int listen(int sockfd,int backlog);
sockfd是要设置的套接字
backlog是服务器的最大等待队列的个数
成功返回0
错误返回-1
使客户端连接到服务器
#include
#include
int connect(int sockfd, const struct sockaddr * addr, socklen_t addrlen);
sockfd表示需要连接到服务器的客户端套接字
addr表示服务器的地址和端口号
addrlen表示的是addr的大小
成功返回0
错误返回-1
服务器用来接受连接
#include
#include
int accept(int sockfd, struct sockaddr * addr, socklen_t *addrlen);
sockfd表示需要连接的客户端的套接字
addr是传出参数,用来传出客户端的IP地址和端口号
addrlen标示传出参数的长度
错误返回-1
TCP服务器的代码实现#include
#include
#include
#include
#include
#include
#include
#include
#define SERV_PORT 9999
#define _BACKLOG_ 10
void Usage()
{
printf("Usage: [ipaddr]\n");
}
int main(int argc,char* argv[])
{
if(argc != 2)
{
Usage();
return -1;
}
//1、调用socket来打开一个网络通信端口
int sock = socket(AF_INET,SOCK_STREAM,0);
if(sock <0)
{
perror("socket");
exit(1);
}
//2、服务器来绑定一个固定的IP地址和端口号
struct sockaddr_in serverSocket;//定义服务端的套接字
struct sockaddr_in clientSocket;//定义客户端的套接字
bzero(&serverSocket,sizeof(serverSocket));//归零初始化
serverSocket.sin_family = AF_INET;//设置地址的类型
serverSocket.sin_addr.s_addr = inet_addr(argv[1]);
serverSocket.sin_port = htons(SERV_PORT);//设置端口号,SERV_PORT为自定义的宏,值设置为9999
if(bind(sock,(struct sockaddr*)&serverSocket,sizeof(struct sockaddr_in))<0)//进行绑定,并进行判断
{
perror("bind");
close(sock);
exit(2);
}
//3、进行监听
if(listen(sock,_BACKLOG_)<0)
{
perror("listen");
close(sock);
exit(3);
}
printf("绑定和监听成功...请等待连接...\n");
while(1)
{
//4、接受连接
socklen_t len = 0;//定义长度len
int clientSock = accept(sock, (struct sockaddr*)&clientSocket,&len);//接受连接
if(clientSock <0)
{
perror("accpet");
exit(4);
}
char buf[INET_ADDRSTRLEN];//定义缓冲区,用来存放IP字符串
memset(buf,0,sizeof(buf));//初始化为0
while(1)
{
char tmpBuf[1024];//定义空间来存储收到与发送的消息
ssize_t ret = read(clientSock,tmpBuf,sizeof(tmpBuf));//从客户端套接字中读入数据
if(ret <0)
{
perror("read");
exit(5);
}
tmpBuf[ret] = '\0';
printf("#client :# %s\n",tmpBuf);//打印从客户端读入的数据
printf("#server :# ");
memset(tmpBuf,'\0',sizeof(tmpBuf));//将buf空间置零
fgets(tmpBuf,sizeof(tmpBuf),stdin);//读入需要发送的数据
write(clientSock,tmpBuf,strlen(tmpBuf));
printf("请等待...\n");
}
}
close(sock);
return 0;
}
#include
#include
#include
#include
#include
#include
#define SERVER_PORT 9999
void Usage()
{
printf("Usage: [client_ip] [client_port]\n");
}
int main(int argc, char* argv[])
{
if(argc != 3)
{
Usage();
return 1;
}
//调用socket来打开一个网络端口
char buf[1024];
char* client_ip = argv[1];
memset(buf,'\0',sizeof(buf));
int sock = socket(AF_INET,SOCK_STREAM,0);
//定义sockaddr_in结构体,并进行初始化
struct sockaddr_in serverSocket;
serverSocket.sin_family = AF_INET;
serverSocket.sin_addr.s_addr = inet_addr(argv[1]);
serverSocket.sin_port = htons(SERVER_PORT);
//进行服务器的链接
int ret = connect(sock,(struct sockaddr*)&serverSocket,sizeof(serverSocket));
if(ret <0)
{
printf("连接失败...\n");
return 2;
}
printf("连接成功...\n");
while(1)
{
printf("#client :# ");
fflush(stdin);
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1] = '\0';
if(strcmp(buf,"quit")==0)
break;
write(sock,buf,sizeof(buf));
printf("请等待服务器响应...\n");
read(sock,buf,sizeof(buf));
printf("#server :# %s",buf);
}
close(sock);
return 0;
}
#include
#include
#include
#include
#include
#include
void Usage()
{
printf("Usage: [ipaddr] [port]\n");
exit(1);
}
int main(int argc,char* argv[])
{
if(argc != 3)
{
Usage();
}
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd <0)
{
perror("sock");
exit(2);
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(argv[2]));
addr.sin_addr.s_addr = inet_addr(argv[1]);
if(bind(sockfd,(struct sockaddr*)&addr,sizeof(addr)) <0)
{
perror("bind");
exit(3);
}
if(listen(sockfd,10) <0)
{
perror("listen");
exit(4);
}
printf("wait connect...\n");
while(1)
{
struct sockaddr_in saddr;
socklen_t straddr = sizeof(saddr);
int fd = accept(sockfd,(struct sockaddr *)&saddr,&straddr);
printf("accept connect...\n");
if(fd <0)
{
continue;
}
pid_t pid = fork();
if(pid <0)
{
perror("fork");
exit(6);
}
else if(pid > 0)
{
printf("find a new client... ip : %s ... port : %d\n",inet_ntoa(saddr.sin_addr),ntohs(saddr.sin_port));
char buf[1024];
while(1)
{
int s = read(fd, buf,sizeof(buf)-1);
if(s <0)
{
perror("read");
exit(7);
}
else if(s == 0)
{
printf("connect quit... ip : %s ... port : %d\n",inet_ntoa(saddr.sin_addr),ntohs(saddr.sin_port));
close(fd);
break;
}
else
{
buf[s] = '\0';
printf("#client: %s\n",buf);
write(fd,buf,strlen(buf));
}
}
close(fd);
wait(pid,NULL,0);
}
else
{
continue;
}
}
close(sockfd);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
void Usage()
{
printf("Usage: [ipaddr] [port]\n");
exit(1);
}
int main(int argc,char* argv[])
{
if(argc != 3)
{
Usage();
}
//打开一个网络端口
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd <0)
{
perror("socket");
exit(2);
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(argv[2]));
addr.sin_addr.s_addr = inet_addr(argv[1]);
if(connect(sockfd,(struct sockaddr*)&addr, sizeof(addr))<0)
{
perror("connect");
exit(3);
}
printf("连接成功...\n");
char buf[1024];
while(1)
{
printf("#client: ");
fflush(stdout);
int s = read(0,buf,sizeof(buf)-1);
if(s <= 0)
{
perror("read");
exit(4);
}
else
{
buf[s-1] = 0;
write(sockfd,buf,strlen(buf));
}
int ret = read(sockfd,buf,sizeof(buf)-1);
if(ret <0)
{
perror("read");
exit(5);
}
else if(ret == 0)
{
printf("连接已断开...\n");
break;
}
else
{
buf[s] = '\0';
printf("#server: %s\n",buf);
}
}
close(sockfd);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
void Usage()
{
printf("Usage: [addrip] [port]\n");
exit(1);
}
int StartUp(char* argv[])
{
//创建接口
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd <0)
{
perror("socket");
exit(2);
}
//进行绑定
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(argv[2]));
addr.sin_addr.s_addr = inet_addr(argv[1]);
if(bind(sockfd,(struct sockaddr *)&addr,sizeof(addr)) <0)
{
perror("bind");
exit(3);
}
//进行监听
if(listen(sockfd,10) <0)
{
perror("listen");
exit(4);
}
return sockfd;
}
void* Myhandler(void* arg)
{
int fd = (int)arg;
char buf[1024];
while(1)
{
ssize_t s = read(fd,buf,sizeof(buf));
if(s <0)//error
{
perror("read");
exit(6);
}
else if(s == 0)//quit
{
printf("client quit...\n");
close(fd);
break;
}
else//write
{
buf[s] = 0;
printf("#client : %s\n",buf);
write(fd,buf,strlen(buf));
}
}
}
int main(int argc,char* argv[])
{
if(argc != 3)
{
Usage();
}
int sockfd = StartUp(argv);
printf("初始化成功...等待连接...\n");
while(1)
{
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
int fd = accept(sockfd,(struct sockaddr*)&addr,&addrlen);
if(fd <0)
{
continue;
}
printf("连接成功... ip : %s , port: %d\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port));
pthread_t td;
pthread_create(&td,NULL,Myhandler,(void*)fd);
pthread_detach(td);
}
close(sockfd);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
static void Usage()
{
printf("Usage : [ipaddr] [port]\n");
exit(1);
}
int StartUp(char* argv[])
{
//打开接口
int sockfd = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(argv[2]));
addr.sin_addr.s_addr = inet_addr(argv[1]);
if(connect(sockfd,(struct sockaddr*)&addr,sizeof(addr)) <0)
{
perror("connect");
exit(2);
}
return sockfd;
}
int main(int argc,char* argv[])
{
if(argc != 3)
{
Usage();
}
int sockfd = StartUp(argv);
printf("连接成功...\n");
while(1)
{
printf("#client : ");
fflush(stdout);
char buf[1024];
ssize_t s = read(0,buf,sizeof(buf)-1);
if(s <= 0)
{
perror("read");
exit(2);
}
else
{
buf[s-1] = '\0';
write(sockfd,buf,strlen(buf));
}
s = read(sockfd,buf,sizeof(buf)-1);
if(s == 0)
{
printf("server quit...\n");
break;
}
else if(s <0)
{
perror("read");
exit(3);
}
else
{
buf[s] = '\0';
printf("#server : %s\n",buf);
}
}
close(sockfd);
return 0;
}