⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basic c socket programming in unix for newbies.txt

📁 1000 HOWTOs for various needs [WINDOWS]
💻 TXT
📖 第 1 页 / 共 2 页
字号:
			   to accept()



	

	When someone is trying to connect to your computer, you must use accept() to get the

	connection. It's very simple to understand: you just get a connection if you accept =)

	



	Next, I'll give you a little example of accept() use because it's a little different 

	from other functions.



	(...)



	  sin_size=sizeof(struct sockaddr_in);

	  if ((fd2 = accept(fd,(struct sockaddr *)&client,&sin_size))==-1){ /* calls accept() */

	    printf("accept() error\n");

	    exit(-1);

	  }



	(...)



	From now on, fd2 will be used for add send() and recv() calls.





  6.6. send()

  ===========



	

	int send(int fd,const void *msg,int len,int flags);



	Let's see the arguments:



		fd -> is the socket descriptor where you want to send data to

		msg    -> is a pointer to the data you want to send

		len    -> is the length of the data you want to send (in bytes)

		flags  -> set it to 0





	This function is used to send data over stream sockets or CONNECTED datagram sockets.

	If you want to send data over UNCONNECTED datagram sockets you must use sendto().

	

	send() returns the number of bytes sent out and it will return -1 on error.





  6.7. recv()

  ===========





	int recv(int fd, void *buf, int len, unsigned int flags);



	Let's see the arguments:



		fd  -> is the socket descriptor to read from

		buf	-> is the buffer to read the information into

		len 	-> is the maximum length of the buffer

		flags 	-> set it to 0





	As I said above about send(), this function is used to send data over stream sockets or 

	CONNECTED datagram sockets. If you want to send data over UNCONNECTED datagram sockets

	you must use recvfrom().



	recv() returns the number of bytes read into the buffer and it'll return -1 on error.





  6.8. sendto()

  =============



	int sendto(int fd,const void *msg, int len, unsigned int flags,

		   const struct sockaddr *to, int tolen);



	Let's see the arguments:



		fd  -> the same as send()

		msg     -> the same as send()

		len	-> the same as send()

		flags	-> the same as send()

		to	-> is a pointer to struct sockaddr

		tolen	-> set it to sizeof(struct sockaddr)



	As you can see, sendto() is just like send(). It has only two more arguments : "to" 

	and "tolen" =) 



	sendto() is used for UNCONNECTED datagram sockets and it returns the number of bytes 

	sent out and it will return -1 on error.





  6.9. recvfrom()

  ===============



	int recvfrom(int fd,void *buf, int len, unsigned int flags

		     struct sockaddr *from, int *fromlen);



	Let's see the arguments:



		fd	-> the same as recv()

		buf	-> the same as recv()

		len	-> the same as recv()

		flags	-> the same as recv()

		from	-> is a pointer to struct sockaddr

		fromlen	-> is a pointer to a local int that should be initialised 

			   to sizeof(struct sockaddr)



	recvfrom() returns the number of bytes received and it'll return -1 on error.





  6.10. close()

  =============



	close(fd);



	close() is used to close the connection on your socket descriptor. If you call close(),

	it won't be no more writes or reads and if someone tries to read/write will receive an 

	error.





  6.11. shutdown()

  ================



	int shutdown(int fd, int how);



	Let's see the arguments:



		fd	-> is the socket file descriptor you want to shutdown

		how	-> you put one of those numbers:

				

					0 -> receives disallowed

					1 -> sends disallowed

					2 -> sends and receives disallowed



	When how is set to 2, it's the same thing as close().



	shutdown() returns 0 on success and -1 on error.





  6.12. gethostname()

  ===================



	#include <unistd.h>



	int gethostname(char *hostname, size_t size);



	Let's see the arguments:



		hostname  -> is a pointer to an array that contains hostname

		size 	  -> length of the hostname array (in bytes)



	

	gethostname() is used to get the name of the local machine.







7. SOME WORDS ABOUT DNS

=======================================



I created this section, because I think you should know what DNS is. DNS stands for "Domain

Name Service" and basically, it's used to get IP addresses. For example, I need to know the

IP address of queima.ptlink.net and through DNS I'll get 212.13.37.13 . 



This is important, because functions we saw above (like bind() and connect()) work with IP

addresses.



To see you how you can get queima.ptlink.net IP address on c, I made a little example:





/* <---- SOURCE CODE STARTS HERE ----> */



#include <stdio.h>

#include <netdb.h>   /* This is the header file needed for gethostbyname() */

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>





int main(int argc, char *argv[])

{

  struct hostent *he;



  if (argc!=2){

     printf("Usage: %s <hostname>\n",argv[0]);

     exit(-1);

  }



  if ((he=gethostbyname(argv[1]))==NULL){

     printf("gethostbyname() error\n");

     exit(-1);

  }



  printf("Hostname : %s\n",he->h_name);  /* prints the hostname */

  printf("IP Address: %s\n",inet_ntoa(*((struct in_addr *)he->h_addr))); /* prints IP address */

}

/* <---- SOURCE CODE ENDS HERE ----> */







8. A STREAM SERVER EXAMPLE

=======================================



In this section, I'll show you a nice example of a stream server. The source code is all

commented so that you ain't no possible doubts =)



Let's start:



/* <---- SOURCE CODE STARTS HERE ----> */



#include <stdio.h>          /* These are the usual header files */

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>





#define PORT 3550   /* Port that will be opened */ 

#define BACKLOG 2   /* Number of allowed connections */



main()

{

 

  int fd, fd2; /* file descriptors */



  struct sockaddr_in server; /* server's address information */

  struct sockaddr_in client; /* client's address information */



  int sin_size;





  if ((fd=socket(AF_INET, SOCK_STREAM, 0)) == -1 ){  /* calls socket() */

    printf("socket() error\n");

    exit(-1);

  }



  server.sin_family = AF_INET;         

  server.sin_port = htons(PORT);   /* Remember htons() from "Conversions" section? =) */

  server.sin_addr.s_addr = INADDR_ANY;  /* INADDR_ANY puts your IP address automatically */   

  bzero(&(server.sin_zero),8); /* zero the rest of the structure */



  

  if(bind(fd,(struct sockaddr*)&server,sizeof(struct sockaddr))==-1){ /* calls bind() */

      printf("bind() error\n");

      exit(-1);

  }     



  if(listen(fd,BACKLOG) == -1){  /* calls listen() */

      printf("listen() error\n");

      exit(-1);

  }



while(1){

  sin_size=sizeof(struct sockaddr_in);

  if ((fd2 = accept(fd,(struct sockaddr *)&client,&sin_size))==-1){ /* calls accept() */

    printf("accept() error\n");

    exit(-1);

  }

  

  printf("You got a connection from %s\n",inet_ntoa(client.sin_addr) ); /* prints client's IP */

  

  send(fd2,"Welcome to my server.\n",22,0); /* send to the client welcome message */

  

  close(fd2); /*  close fd2 */

}

}



/* <---- SOURCE CODE ENDS HERE ----> */







9. A STREAM CLIENT EXAMPLE

=======================================



/* <---- SOURCE CODE STARTS HERE ----> */



#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>        /* netbd.h is needed for struct hostent =) */



#define PORT 3550	  /* Open Port on Remote Host */

#define MAXDATASIZE 100   /* Max number of bytes of data */



int main(int argc, char *argv[])

{

  int fd, numbytes;	  /* files descriptors */

  char buf[MAXDATASIZE];  /* buf will store received text */

  

  struct hostent *he;         /* structure that will get information about remote host */

  struct sockaddr_in server;  /* server's address information */



  if (argc !=2) {	      /* this is used because our program will need one argument (IP) */

    printf("Usage: %s <IP Address>\n",argv[0]);

    exit(-1);

  }



  if ((he=gethostbyname(argv[1]))==NULL){	/* calls gethostbyname() */

    printf("gethostbyname() error\n");

    exit(-1);

  }



  if ((fd=socket(AF_INET, SOCK_STREAM, 0))==-1){  /* calls socket() */

    printf("socket() error\n");

    exit(-1);

  }



  server.sin_family = AF_INET;

  server.sin_port = htons(PORT); /* htons() is needed again */

  server.sin_addr = *((struct in_addr *)he->h_addr);  /*he->h_addr passes "*he"'s info to "h_addr" */

  bzero(&(server.sin_zero),8);



  if(connect(fd, (struct sockaddr *)&server,sizeof(struct sockaddr))==-1){ /* calls connect() */

    printf("connect() error\n");

    exit(-1);

  }



  if ((numbytes=recv(fd,buf,MAXDATASIZE,0)) == -1){  /* calls recv() */

    printf("recv() error\n");

    exit(-1);

  }



      buf[numbytes]='\0';



      printf("Server Message: %s\n",buf); /* it prints server's welcome message =) */



      close(fd);   /* close fd =) */

}



/* <---- SOURCE CODE ENDS HERE ----> */







10. LAST WORDS

=======================================





As I'm just a simple human, it's almost certain that there are some errors on this document.

When I say errors I mean English errors (because my language is not the English) but also

technical errors. Please email me if you detect any error =)



But you must understand that this is the first version of this document, so , it's natural not 

to be very complete (as matter of fact I think it is ) and it's also very natural to have 

stupid errors. However, I can be sure that source code presented in this document works fine.





If you need help concerning this subject you can email me at <BracaMan@clix.pt>





SPECIAL THANKS TO: Ghost_Rider (my good old mate), Raven (for letting me write this tutorial) 

		   and all my friends =)







11. COPYRIGHT

=======================================



All copyrights are reserved. You can distribute this tutorial freely, as long you don't change

any name or URL. You can't change a line or two, or add another lines, and then claim that this

tutorial is yours. If you want to change something, please email me at <BracaMan@clix.pt>.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -