A good code related to socket select

Source: Internet
Author: User
Tags set socket
TCP socket connection/read/write operations implemented by C. Use fcntl to set non-blocking connections to achieve connect timeout; Use the select method to set socket read/write timeout. This example can be compiled and run on Windows/Unix systems.

Source File connector. c

The original Code failed to be compiled in windows. It was discovered only when qzj asked today. Because asynchronous processing is added, no compatibility processing is performed on this part of the code. In the spirit of meticulous learning, I modified the source code again. The following code is compiled and executed in VC ++ 6 and Linux Through

/* </P> <p> * on UNIX: </P> <p> * Cc-C connector. c </P> <p> * Cc-O connector ctor. O </P> <p> * on Windows NT: </P> <p> * Open ctor. C in Visual Studio </P> <p> * press 'f7 'to link -- a project to be created </P> <p> * Add wsock32.lib to the link section under project setting </P> <p> * press 'f7 'Again </P> <p> * running: </P> <p> * type 'ctor ctor 'for usage </P> <p> */</P> <p> # include <std Io. h> </P> <p> # include <stdlib. h> </P> <p> # include <string. h> </P> <p> # include <stdarg. h> </P> <p> # include <errno. h> </P> <p> # include <fcntl. h> </P> <p> # ifdef Win32 </P> <p> # include <winsock2.h> </P> <p> # else </P> <p> # include <unistd. h> </P> <p> # include <sys/types. h> </P> <p> # include <sys/socket. h> </P> <p> # include <sys/IOCTL. h> </P> <p> # include <netinet/in. h> </P> <p> # include <ARPA/inet. h> </P> <p> # include <netdb. h> </P> <p> # En DIF </P> <p> # ifndef inaddr_none </P> <p> # define inaddr_none 0 xffffffff </P> <p> # endif </P> <p> # define max_string_len 1024 </P> <p> # define bufsize 2048 </P> <p> # ifndef Win32 </P> <p> # define socket int </P> <p> # else </P> <p> # define errno wsagetlasterror () </P> <p> # define close (a) closesocket (a) </P> <p> # define write (a, B, c) Send (A, B, c, 0) </P> <p> # define read (a, B, c) Recv (a, B, c, 0) </P> <p> # endif </P> <p> char Buf [bufsize ]; </P> <p> static char I _host [max_string_len];/* site name */</P> <p> static char I _port [max_string_len]; /* Port Number */</P> <p> void err_doit (INT errnoflag, const char * FMT, va_list AP ); </P> <p> void err_quit (const char * FMT ,...); </P> <p> int tcp_connect (const char * Host, const unsigned short port); </P> <p> void print_usage (); </P> <p> // xnet_select X defines </P> <p> # define read_status 0 </P> <p> # define write _ Status 1 </P> <p> # define excpt_status 2 </P> <p>/* </P> <p> S-socket </P> <p> sec-timeout seconds </P> <p> USEC-Timeout microseconds </P> <p> X-select status </P> <p> */</P> <p> socket xnet_select (socket s, int sec, int USEC, short X) </P> <p >{</P> <p> int ST = errno; </P> <p> struct timeval; </P> <p> fd_set FS; </P> <p>. TV _sec = sec; </P> <p>. TV _usec = USEC; </P> <p> fd_zero (& FS); </P> <p> fd_set (S, & FS); </P> <p> S Witch (x) {</P> <p> case read_status: </P> <p> ST = select (S + 1, & FS, 0, 0, & to); </P> <p> break; </P> <p> case write_status: </P> <p> ST = select (S + 1, 0, & FS, 0, & to); </P> <p> break; </P> <p> case excpt_status: </P> <p> ST = select (S + 1, 0, 0, & FS, & to); </P> <p> break; </P> <p >}</P> <p> return (ST ); </P> <p >}</P> <p> int tcp_connect (const char * Host, const unsigned short port) </P> <p >{</P> <p> unsigned long non_blocking = 1; </P> <p> unsigned long blocking = 0; </P> <p> int ret = 0; </P> <p> char * Transport = "TCP"; </P> <p> struct hostent * Phe; /* pointer to host information entry */</P> <p> struct protoent * PPE; /* pointer to protocol information entry */</P> <p> struct sockaddr_in sin;/* an Internet endpoint address */</P> <p> socket S; /* socket Descriptor and socket type */</P> <p> int error; </P> <p> # ifdef Win32 </P> <p >{</ P> <p> word wversionrequested; </P> <p> wsadata; </P> <p> int err; </P> <p> wversionrequested = makeword (2, 0); </P> <p> err = wsastartup (wversionrequested, & wsadata ); </P> <p> If (Err! = 0) {</P> <p>/* tell the user that we couldn't find a usable */</P> <p>/* Winsock DLL. */</P> <p> printf ("can't initialize socket Library/N"); </P> <p> exit (0 ); </P> <p >}</P> <p> # endif </P> <p> memset (& sin, 0, sizeof (SIN); </P> <p> sin. sin_family = af_inet; </P> <p> If (sin. sin_port = htons (port) = 0) </P> <p> err_quit ("invalid PORT/" % d/"/N", Port ); </P> <p>/* map host name to IP address, allowi Ng for dotted decimal */</P> <p> If (PHE = gethostbyname (host) </P> <p> memcpy (& sin. sin_addr, Phe-> h_addr, Phe-> h_length); </P> <p> else if (sin. sin_addr.s_addr = inet_addr (host) = inaddr_none) </P> <p> err_quit ("can't get/" % S/"host entry/N", host ); </P> <p>/* map transport protocol name to Protocol Number */</P> <p> If (PPE = getprotobyname (Transport) = 0) </P> <p> err_quit ("can't get/" % S/"P Rotocol entry/N ", transport); </P> <p>/* allocate a socket */</P> <p> S = socket (pf_inet, sock_stream, PPE-> p_proto); </P> <p> If (S <0) </P> <p> err_quit ("can't create socket: % s/n ", strerror (errno )); </P> <p>/* connect the socket with timeout */</P> <p> # ifdef Win32 </P> <p> ioctlsocket (S, fionbio, & non_blocking); </P> <p> # else </P> <p> IOCTL (S, fionbio, & non_blocking ); </P> <p> # endif </P> <p> // fcntl (S, f_setfl, o_no Nblock); </P> <p> If (connect (S, (struct sockaddr *) & sin, sizeof (SIN) =-1) {</P> <p> struct timeval TV; </P> <p> fd_set writefds; </P> <p> // set the connection timeout </P> <p> TV. TV _sec = 10; // number of seconds </P> <p> TV. TV _usec = 0; // millisecond </P> <p> fd_zero (& writefds); </P> <p> fd_set (S, & writefds ); </P> <p> If (select (S + 1, null, & writefds, null, & TV )! = 0) {</P> <p> If (fd_isset (S, & writefds) {</P> <p> int Len = sizeof (error ); </P> <p> // The following sentence must be specific to the firewall </P> <p> If (getsockopt (S, sol_socket, so_error, (char *) & error, & Len) <0) </P> <p> goto error_ret; </P> <p> If (error! = 0) </P> <p> goto error_ret; </P> <p >}</P> <p> else </P> <p> goto error_ret; // timeout or error happen </P> <p >}</P> <p> else goto error_ret ;; </P> <p> # ifdef Win32 </P> <p> ioctlsocket (S, fionbio, & blocking ); </P> <p> # else </P> <p> IOCTL (S, fionbio, & blocking ); </P> <p> # endif </P> <p >}</P> <p> else {</P> <p> error_ret: </P> <p> close (s); </P> <p> err_quit ("can't connect to % s: % d/N", host, port); </P> <p >}</P> <p> return s; </ P> <p >}</P> <p> void err_doit (INT errnoflag, const char * FMT, va_list AP) </P> <p >{</P> <p> int errno_save; </P> <p> char Buf [max_string_len]; </P> <p> errno_save = errno; </P> <p> vsprintf (BUF, FMT, AP); </P> <p> If (errnoflag) </P> <p> sprintf (BUF + strlen (BUF), ": % s", strerror (errno_save); </P> <p> strcat (BUF, "/N"); </P> <p> fflush (stdout); </P> <p> fputs (BUF, stderr ); </P> <p> fflush (null); </P> <p> return; </P> <p>} </P> <p>/* print a message and terminate. */</P> <p> void err_quit (const char * FMT ,...) </P> <p >{</P> <p> va_list AP; </P> <p> va_start (AP, FMT ); </P> <p> err_doit (0, FMT, AP); </P> <p> va_end (AP); </P> <p> exit (1 ); </P> <p >}</P> <p> # ifdef Win32 </P> <p> char * optarg; </P> <p> char getopt (int c, char * V [], char * opts) </P> <p >{</P> <p> static int now = 1; </P> <p> char * P; </P> <p> If (now> = c) Return EOF; </P> <p> If (V [now] [0] = '-' & (P = strchr (OPTs, V [now] [1]) {</P> <p> optarg = V [now + 1]; </P> <p> now + = 2; </P> <p> return * P; </P> <p >}</P> <p> return EOF; </P> <p >}</P> <p> # else </P> <p> extern char * optarg; </P> <p> # endif </P> <p> # define required (a) if (! A) {return-1 ;}</P> <p> int Init (INT argc, char * argv []) </P> <p >{</P> <p> char C; </P> <p> // int I, optlen; </P> <p> // int slashcnt; </P> <p> I _host [0] = '/0 '; </P> <p> I _port [0] = '/0'; </P> <p> while (C = getopt (argc, argv, "H: P :? "))! = EOF) {</P> <p> If (C = '? ') </P> <p> return-1; </P> <p> switch (c) {</P> <p> case 'H ': </P> <p> required (optarg); </P> <p> strcpy (I _host, optarg); </P> <p> break; </P> <p> case 'p': </P> <p> required (optarg); </P> <p> strcpy (I _port, optarg ); </P> <p> break; </P> <p> default: </P> <p> return-1; </P> <p >}</P> <p>/* </P> <p> * There is no default value for hostname, port number, </P> <p> * password or Uri </P> <p> */</P> <p> If (I _host [0] = '/0' | | I _port [0] = '/0 ') </P> <p> return-1; </P> <p> return 1; </P> <p >}</P> <p> void print_usage () </P> <p >{</P> <p> char * usage [] = </P> <p >{</P> <p> "Usage: ", </P> <p>"-H host name ", </P> <p>"-P port ", </P> <p>" Example: ", </P> <p>"-H 127.0.0.1-P 4001 ", </P> <p >}; </P> <p> int I; </P> <p> for (I = 0; I <sizeof (usage)/sizeof (char *); I ++) </P> <p> printf ("% s/n", usage [I]); </P> <p> return; </P> <p >}</P> <p> int main (INT argc, char * argv []) </P> <p >{</P> <p> socket FD; </P> <p> int N; </P> <p>/* parse command line etc... */</P> <p> If (Init (argc, argv) <0) {</P> <p> print_usage (); </P> <p> exit (1); </P> <p >}</P> <p> Buf [0] = '/0 '; </P> <p>/* pack the info into the buffer */</P> <p> strcpy (BUF, "helloworld "); </P> <p>/* Make connection to the server */</P> <p> FD = tcp_connect (I _host, (unsigned short) atoi (I _port )); </P> <p> If (xnet_select (FD, 0,500, write_status)> 0) {</P> <p>/* send off the message */</P> <p> write (FD, Buf, strlen (BUF )); </P> <p >}</P> <p> else {</P> <p> err_quit ("socket I/O write timeout % s: % s/n ", I _host, I _port); </P> <p >}</P> <p> If (xnet_select (FD, 3, 0, read_status)> 0) {</P> <p>/* display the server response */</P> <p> printf ("Server Response:/N "); </P> <p> N = read (FD, Buf, bufsize); </P> <p> Buf [N] = '/0 '; </P> <p> printf ("% s/n", Buf ); </P> <p >}</P> <p> else {</P> <p> err_quit ("socket I/O read timeout % s: % s/n ", I _host, I _port); </P> <p >}</P> <p> close (FD ); </P> <p> # ifdef Win32 </P> <p> wsacleanup (); </P> <p> # endif </P> <p> return 0; </P> <p >}</P> <p>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.