Linux网络编程学习笔记(一)–Socket编程

  • Post author:
  • Post category:linux


 
(一)1.实现简单的客户端发消息服务器端接受消息.
     2.回射客户/服务器
//服务器端server1.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

void error_handling(char* message)
{
	fputs(message,stderr);
	fputc('\n',stderr);
	exit(1);
}
	

int main()
{
	int listenfd=socket(AF_INET,SOCK_STREAM,0);
	if(listenfd<0)
	error_handling("socket");
	
	struct sockaddr_in servaddr;
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family=AF_INET;
	servaddr.sin_port=htons(5188);
	servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
	
	/***************************************************************/
	//这三句的作用是:当客户端关闭后,可以立即重启,而不需要经过一段时间的TIME_WAIT的等待
	int on=1;
	if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0)
	error_handling("socket");
	/***************************************************************/

	if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
	error_handling("bind");

	if(listen(listenfd,SOMAXCONN)<0)
	error_handling("listen");

	struct sockaddr_in peeraddr;
	socklen_t peerlen=sizeof(peeraddr);

	int conn;
	if((conn=accept(listenfd,(struct sockaddr*)&peeraddr,&peerlen))<0)
	error_handling("accept");	
	

	printf("IP=%s port=%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));//打印对等方的IP地址和端口号
	
	char recvbuf[1024];
	while(1)
	{
		memset(recvbuf,0,sizeof(recvbuf));
		int ret=read(conn,recvbuf,sizeof(recvbuf));
		fputs(recvbuf,stdout);
		//write(conn,recvbuf,ret);   如果只是想实现简单的客户端发数据,服务器接受并且显示,则屏蔽这句
	}
	
close(conn);close(listenfd);
	return 0;
	}

	
	
	
//客户端  client1.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

void error_handling(char* message)
{
	fputs(message,stderr);
	fputc('\n',stderr);
	exit(1);
}

int main()
{
	int sock;
	sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
	if(sock<0)
	error_handling("sock");

	struct sockaddr_in servaddr;
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family=AF_INET;
	servaddr.sin_port=htons(5188);
	servaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
	
	if(connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
	error_handling("connect");
	
	char sendbuf[1024]={0};
	char recvbuf[1024]={0};
	
	while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL)
	{
                //若保留这个while循环中的屏蔽掉的语句,实现的是回射客户/服务器
		write(sock,sendbuf,strlen(sendbuf));   //不是sizeof的原因:sizeof是1024,strlen是recvbuf[]从输入流读了多少字节就取多少个
		//read(sock,recvbuf,sizeof(recvbuf));    如果只是想实现简单的客户端发数据,服务器接受并且显示,则屏蔽这句
		//fputs(recvbuf,stdout);                  如果只是想实现简单的客户端发数据,服务器接受并且显示,则屏蔽这句  
		
		memset(sendbuf,0,sizeof(sendbuf));
		//memset(recvbuf,0,sizeof(recvbuf));        如果只是想实现简单的客户端发数据,服务器接受并且显示,则屏蔽这句
	}
	
	
	close(sock);
	return 0;
}
		

(二)实现一个服务器端可以同时和多个客户端通信

//server.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

void error_handling(char* message)
{
	fputs(message,stderr);
	fputc('\n',stderr);
	exit(1);
}
	

int main()
{
	int listenfd=socket(AF_INET,SOCK_STREAM,0);
	if(listenfd<0)
	error_handling("socket");
	
	struct sockaddr_in servaddr;
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family=AF_INET;
	servaddr.sin_port=htons(5188);
	servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
	
	int on=1;
	if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0)
	error_handling("socket");
	if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
	error_handling("bind");

	if(listen(listenfd,SOMAXCONN)<0)
	error_handling("listen");

	struct sockaddr_in peeraddr;
	socklen_t peerlen=sizeof(peeraddr);

	int conn;
	//if((conn=accept(listenfd,(struct sockaddr*)&peeraddr,&peerlen))<0)
	//error_handling("accept");	
	

	//printf("IP=%s port=%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));//打印对等方的IP地址和端口号
	
	//char recvbuf[1024];
	//while(1)
	//{
	//	memset(recvbuf,0,sizeof(recvbuf));
	//	int ret=read(conn,recvbuf,sizeof(recvbuf));
	//	fputs(recvbuf,stdout);
	//	write(conn,recvbuf,ret);
	//}
	
//close(conn);close(listenfd);
//	return 0;
	//}

  pid_t pid;
  while(1)
{
  if((conn=accept(listenfd,(struct sockaddr*)&peeraddr,&peerlen))<0)
	error_handling("accept");
  
  printf("ip=%s  port=%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));

 pid=fork();

 if(pid==-1)
 error_handling("fork");
 
 if(pid==0)
{
  close(listenfd);//子进程关闭监听套接字
  
 char recvbuf[1024];

 while(1)
{
  memset(recvbuf,0,sizeof(recvbuf));
   int ret=read(conn,recvbuf,sizeof(recvbuf));
    fputs(recvbuf,stdout);
    write(conn,recvbuf,ret);
}
}

else close(conn);//父进程关闭连接套接字
}

return 0;
}

	
//client.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

void error_handling(char* message)
{
	fputs(message,stderr);
	fputc('\n',stderr);
	exit(1);
}

int main()
{
	int sock;
	sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
	if(sock<0)
	error_handling("sock");

	struct sockaddr_in servaddr;
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family=AF_INET;
	servaddr.sin_port=htons(5188);
	servaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
	
	if(connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
	error_handling("connect");
	
	char sendbuf[1024]={0};
	char recvbuf[1024]={0};
	
	while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL)
	{
		write(sock,sendbuf,strlen(sendbuf));   //不是sizeof的原因:sizeof是1024,strlen是读多少字节就取多少个
		read(sock,recvbuf,sizeof(recvbuf));
		fputs(recvbuf,stdout);
		
		memset(sendbuf,0,sizeof(sendbuf));
		memset(recvbuf,0,sizeof(recvbuf));
	}
	
	
	close(sock);
	return 0;
}
		



版权声明:本文为qq_34793133原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。