linux网络编程TCP篇

参照例程编写的基于TCP的通信程序。
server段建立之后,键入客户端运行命令和主机地址,能实现客户端中输入的信息打印到服务端。
 
客户端:
#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h>

#define portnumber 3333

struct sockaddr_in serveraddr;

int sockfd;

char buffer[1024];



/**********************************************
hostent的定义如下:
struct hostent {
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
#define h_addr h_addr_list[0]
}

h_name – 地址的正式名称。
h_aliases – 空字节-地址的预备名称的指针。
h_addrtype –地址类型; 通常是AF_INET。  
h_length – 地址的比特长度。
h_addr_list – 零字节-主机网络地址指针。网络字节顺序。
h_addr - h_addr_list中的第一地址。

**********************************************/
struct hostent *host;




int main(int argc,char *argv[])
{
     if(argc!=2)
     	{
     	     printf("abusent IP adress");
			 exit(1);
     	}
	 
     if((host=gethostbyname(argv[1]))==NULL)
     	{
     	     fprintf(stderr,"gethostname errror\n");
     	}

	 if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
	 	{
	 	   fprintf(stderr,"socket cretate feault:&s\n",error(errno));
	 	   exit(1);
	 	}

     brezo(&serveraddr,sizeof(struct sockaddr_in)); //注意:要交关键字struct  !
	 serveraddr.sin_family=AF_INET;
	 serveraddr.sin_port=htons(portnumber);
	 serveraddr.sin_addr=*((struct in_addr *)host->h_addr);
	 //serveraddr.sin_addr.s_addr=host->h_addr;

	 if(connect(sockfd,(struct sockaddr *)(&serveraddr),sizeof(struct sockaddr))==-1)
	 	{
	 	   fprintf(stderr,"Connect fealut:%s\n",error(errno));
		   exit(1);
	 	}

	 printf("please input something:\n");
	 
	 fgets(buffer, sizeof(buffer),stdin);

	 write(sockfd,buffer,strlen(buffer));

	 close(sockfd);
	 exit(0);
}

服务端:

#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h> 

#define  portnumber 3333

struct sockaddr_in server_addr;
struct sockaddr_in client_addr;

int newfd;
int sockfd;
int addrsize;
char buffer[1024];

int main(int argc,char *argv[])     //此处不带参数也可
{
    int nbytes;
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    	{
             // printf("scoket create error\n");
             fprintf(stderr,"scoket create error:%s\n\a",strerror(errno));
			  exit(1);
	    }

	bzero(&server_addr,sizeof(struct sockaddr_in)); 
	server_addr.sin_family=AF_INET;
	server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	server_addr.sin_port=htons(portnumber);

/*************************************************************************
int bind(int socket, const struct sockaddr *address,socklen_t address_len)

绑定IP,端口信息等到套接字。
socket:是一个套接字。
address:是一个sockaddr结构指针,该结构中包含了要结合的地址和端口号。
address_len:确定address缓冲区的长度
****************************************************************************/
	if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
		{
             fprintf(stderr,"bind error:%s\n\a",strerror(errno));
		//上一函数用于打印相应的错误信息	 ,\a表示响铃(电脑的声音)
			 exit(1);
	    }

	/*******************************************************************
	使得一个进程可以接受其它进程的请求,从而成为
	一个服务器进程。在TCP服务器编程中listen函数把进程
	变为一个服务器,并指定相应的套接字变为被动连接。
	*********************************************************************/
	if(listen(sockfd,5)==-1)
		{
		    // printf("listen error\n");
             fprintf(stderr,"listen error:%s\n\a",strerror(errno));
			 exit(1);
		}

	addrsize=sizeof(struct sockaddr_in);
	
    while(1)
    	{
/**************************************************************
accept( SOCKET s, struct sockaddr FAR* addr,int FAR* addrlen);

s:套接口描述字,该套接口在listen()后监听连接。
addr: 接收为通讯层所知的连接实体的地址。
                     Addr参数的实际格式由套接口创建时所产生的地址族确定。
addrlen: 指向存有addr地址长度的整型数。
****************************************************************/
    	     if((newfd=accept(sockfd,(struct sockaddr *)&(client_addr),&addrsize))==-1)
			 	{
			 	  //  printf("accept error\n");
                    fprintf(stderr,"accept error:%s\n\a",strerror(errno));
					exit(1);
			 	}
			 
             fprintf(stderr,"server get connection from %s\n",inet_ntoa(client_addr.sin_addr));
			 //inet_addr 和inet_ntoa用于在二进制地址格式与点分十进制字符串表示之间转换

			 if((nbytes=read(newfd,buffer,1024))==-1) 
			 	{
	       //		 	    printf("read error\n");
                    fprintf(stderr,"read error:%s\n\a",strerror(errno));
					exit(1);
			 	}
/*****************************************************
与read对应的则是write(sockfd,buffer,strlen(buffer)); 
注意:server端读的是new,  client端写的是sockfd

*****************************************************/
			 
	         buffer[nbytes]='\0';		 
    	     printf("server received:%s\n",buffer);
			 close(newfd);
    	}
//把while(1)去掉后客户端结束时它也能结束
		
        close(sockfd);
        exit(0);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值