这几天的socket编程

来源:互联网 发布:dnf优化后盒子无法换装 编辑:程序博客网 时间:2024/05/20 21:59

突然想以后学编程搞软件了,刚开始学编程,看了刘学勇、陈建伟老师出版的《精通linux》编程,开始尝试自己编写socket,代码有很多参考刘老师的书和甘刚老师《linux/Unix网络编程》,出现了很多问题,现在记录下来。使用vmware的虚拟机,centos6的操作系统,新手学习,还是菜鸟,求轻喷,也请大家多指教。

代码如下:

服务器部分:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<arpa/inet.h>

#define LISTENQ 5
#define MAXLINE 10
int main()
{
  int n,connfd,sockfd;
  struct sockaddr_in servaddr;
  socklen_t len;
  struct sockaddr_in cliaddr; 

  char buff[MAXLINE];

  sockfd=socket(AF_INET,SOCK_STREAM,0);
  if(sockfd<0)
  {
          printf("sockfd error");
          return -1;
  }
  //printf("1");
  bzero(&servaddr,sizeof(servaddr));
  servaddr.sin_family=AF_INET;
  servaddr.sin_port=htons(8080);
  servaddr.sin_addr.s_addr=htonl(INADDR_ANY);


  if(bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0)
  {
          printf("bind error");
          return -1;
  }
  printf("listening...\n");
  listen(sockfd,LISTENQ);

   len=sizeof(cliaddr);
    if((connfd=accept(sockfd,NULL,NULL))==-1)
    {
      printf("accept error");
      return -1;
    }
//    printf("it is %d\n",connfd);
    printf("you got a connection from %s,port is %d\n",inet_ntoa(cliaddr.sin_addr),htons(cliaddr.sin_port));
    memset(buff,0,MAXLINE);
    fgets(buff,MAXLINE,stdin);
     if(send(connfd,buff,MAXLINE,0)<0)
     {
        printf("send error1");
     }
     buff[n-1]='\0';
//        printf("send error %s");
//    send(connfd,"welcome\n",8,0);


    close(connfd);
  close(sockfd);
  return 0;
}

客户端部分:

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


#define MAXLINE 10


int main(int argc,char **argv)
{
  int sockfd,n;
  struct sockaddr_in servaddr;
  char buff[MAXLINE];


  sockfd=socket(AF_INET,SOCK_STREAM,0);
  if(sockfd<0)
  {
    printf("socket error");
    return -1;

  }
  bzero(&servaddr,sizeof(servaddr));
  servaddr.sin_family=AF_INET;
  servaddr.sin_port=htons(8080);
//  servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
  if(inet_aton(argv[1],(struct in_addr *)&servaddr.sin_addr)==0)
  {printf("er");}


  printf("connecting...\n");
  if(connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
  {
    printf("connect error");
    return -1;
  }


//  fgets(buff,MAXLINE,stdin);
//  n=write(sockfd,buff,strlen(buff));
//  buff[n]='\0';

  if((n=recv(sockfd,buff,MAXLINE,0))==-1)
  {
    printf("recv error");
    return -1;
  }
  buff[n-1]='\0';
  printf("receive: %s\n",buff);


  close(sockfd);
  return 0;
}

没有养成一个写注释的好习惯,从今以后注意!其中很多加“//”的地方都是为了调试方便添加的,因为gdb用的还不是很熟练。跑题了,该程序是实现了一个服务器向客户端发送任何一句话,客户端接收并显示的功能,调试了好久,虽然最终还是有些许bug,但还算是基本实现功能。

遇到的问题

1、执行gcc service.o -o service 时候,链接出错!第一次出错是因为我使用 bzero()函数把数组给置零,有多蠢!人家不是用来干那事的!第二次出错是我在执行gcc -c service.c -o service.o 的时候没有加-c参数,没有进行编译,出的错我脑袋都大了,一直提示找不到main的入口函数,总算是运气好,把错找出来了,要不真的欲哭无泪。

2、最主要的就是segmentation fault,注释掉 printf("you got a connection from %s,port is %d\n",inet_ntoa(cliaddr.sin_addr),htons(cliaddr.sin_port));这句话就可以实现,但是有就不可以。刚开始不知道原因,在网上搜了好多,看到一篇谁的博客(不好意思忘记了,原谅我,如果您看见我的帖子给我留言,我会给您补上姓名道谢),说是没有加<arpa/inet.h>,说的确实正确,加上之后果然没错了。

3、上边的segmentation fault解决之后,又出现了新的segmentation fault,看了好多大神说可以用gdb调core文件看,但真心不是我的水平,出现的栈地址都不知所云,但我通过总结,知道大体是指针错误,而且就出在数组上,于是我给数组在使用之前先全都置0,也就是  memset(buff,0,MAXLINE);问题真的解决了。

以上就是我写这个小socket函数的收获,刚开始学,积累经验,还请大家多指教。ps:以后参考大家的帖子我会属上姓名的。