📄 windows internet programming {part 2}.html
字号:
| Unix Function | Windows Function |
+===============+==================+
| close() | closesocket() |
+---------------+------------------+
| ioctl() | ioctlsocket() |
+---------------+------------------+
| read() | recv() |
+---------------+------------------+
| write() | send() |
+---------------+------------------+
</pre>
<p> FIG 1. - Comparison of Windows and Unix Socket functions.
<br>
<p>
<hr SIZE=1 WIDTH="70%">
<br>
<p>8.0<a NAME="8"></a> BLOCKING ROUTINES
<br>=======================================
<p>In windows you can use blocking routines but they are not recommended.
In windows 3.1
<br>using the event driven paradigm it is possible to have a blocked operation
disturbed
<br>by other event driven activity.
<p>Soon you will not be able to have blocking routines in Winsock applications
so it is
<br>not recommended you use them at all in this scenario as this would
limit distribution
<br>possibilities.
<br>
<p>
<hr SIZE=1 WIDTH="70%">
<br>
<p>9.0 <a NAME="9"></a>ADDITIONAL FUNCTIONS
<br>=======================================
<p>In windows there are some functions which aren't seen in UNIX sockets.
In every
<br>windows socket program you must call WSAStarup() before you can call
any socket
<br>functions or use any code.
<p>Additionally every WSAStartup() function has a corresponding WSACleanup()
which
<br>shuts down the Winsock and cleans up after us.
<p>Every Windows socket program must contain both of these functions.
<br>
<p>
<hr SIZE=1 WIDTH="70%">
<br>
<p>10.0 <a NAME="10"></a>PORTING CODE
<br>=======================================
<p>Now that we have discussed the different parts of the program in Unix
and its relevant
<br>Windows parts we can look at some real code.
<br>
<br>
<p>[ 10.1 ]<a NAME="10.1"></a> DNS PROGRAM
<p>The first program we come across is Bracamans DNS application. Here抯
the Unix Code.
<p>/* <---- SOURCE CODE STARTS HERE ----> */
<p>#include <stdio.h>
<br>#include <netdb.h> /* This is the header file needed
for gethostbyname() */
<br>#include <sys/types.h>
<br>#include <sys/socket.h>
<br>#include <netinet/in.h>
<br>
<p>int main(int argc, char *argv[])
<br>{
<br> struct hostent *he;
<p> if (argc!=2){
<br> printf("Usage: %s <hostname>\n",argv[0]);
<br> exit(-1);
<br> }
<p> if ((he=gethostbyname(argv[1]))==NULL){
<br> printf("gethostbyname() error\n");
<br> exit(-1);
<br> }
<p> printf("Hostname : %s\n",he->h_name); /* prints the hostname
*/
<br> printf("IP Address: %s\n",inet_ntoa(*((struct in_addr *)he->h_addr)));
/* prints IP address */
<br>}
<br>/* <---- SOURCE CODE ENDS HERE ----> */
<br>
<br>
<p>This is a very small but still a very useful program. If we attempt
to compile this
<br>right away under Microsoft Visual C++ We will get an error saying that
it can not
<br>find an include file, so our first duty is to remove all of the Unix
Socket include
<br>files and replace them with the line:
<p>#include <windows.h>
<p>remembering to leave stdio.h right where it is.
<br>When I tried compiling it now I got several more errors so I changed
the
<br>main() fuction from what it is above to:
<p>void main(int argc, char **argv) and the program then compiled.
<p>However I then got several linker errors. Remember when socket programming
on windows
<br>you must link to the file Wsock32.lib.
<p>After I linked to the proper .lib file the program compiles perfectly,
without the
<br>need to touch a single line of the socket code!!
<p>This is how compatible different platforms can be with socket code,
however this is a
<br>very small program and this is not usually the case. The following
is the windows
<br>source code for the port of Bracamans DNS program.
<p>Remember you will get an error unless you include WSAStartup() and WSACleanup()!!
<br>
<p>/* <---- SOURCE CODE STARTS HERE ----> */
<p>#include <windows.h>
<br>#include <stdio.h>
<p>int main(int argc, char *argv[])
<br>{
<p> WSADATA wsdata;
<p> WSAStartup(0x0101,&wsdata);
<p> struct hostent *he;
<p> if (argc! = 2)
<br> {
<br> printf("Usage: %s hostname\n",argv[0]);
<br> return -1;
<br> }
<p> if ((he = gethostbyname(argv[1])) == NULL)
<br> {
<br> printf("gethostbyname() error\n");
<br> return -1;
<br> }
<p> printf("Hostname : %s\n",he->h_name);
/* prints the hostname */
<br> printf("IP Address: %s\n",inet_ntoa(*((struct in_addr *)he->h_addr)));
/* prints IP address */
<p> WSACleanup();
<br> return -1;
<p>}
<br>/* <---- SOURCE CODE ENDS HERE ----> */
<br>
<p>This program has almost as few lines as the UNIX alternative and requires
practically
<br>no porting at all!
<p>Like I said you wouldn抰 usually have a program that runs on windows
with such little altering.
<br>Lets discuss porting Bracamans TCP streaming server.
<br>
<p>[ 10.2 ] <a NAME="10.2"></a>STREAMING SERVER
<br>
<p>/* <---- SOURCE CODE STARTS HERE ----> */
<p>#include <stdio.h>
/* These are the usual header files */
<br>#include <sys/types.h>
<br>#include <sys/socket.h>
<br>#include <netinet/in.h>
<br>
<p>#define PORT 3550 /* Port that will be opened */
<br>#define BACKLOG 2 /* Number of allowed connections */
<p>main()
<br>{
<br>
<br> int fd, fd2; /* file descriptors */
<p> struct sockaddr_in server; /* server's address information */
<br> struct sockaddr_in client; /* client's address information */
<p> int sin_size;
<br>
<p> if ((fd=socket(AF_INET, SOCK_STREAM, 0)) == -1 ){ /* calls
socket() */
<br> printf("socket() error\n");
<br> exit(-1);
<br> }
<p> server.sin_family = AF_INET;
<br> server.sin_port = htons(PORT); /* Remember htons()
from "Conversions" section? =) */
<br> server.sin_addr.s_addr = INADDR_ANY; /* INADDR_ANY puts
your IP address automatically */
<br> bzero(&(server.sin_zero),8); /* zero the rest of the structure
*/
<p>
<br> if(bind(fd,(struct sockaddr*)&server,sizeof(struct sockaddr))==-1){
/* calls bind() */
<br> printf("bind() error\n");
<br> exit(-1);
<br> }
<p> if(listen(fd,BACKLOG) == -1){ /* calls listen() */
<br> printf("listen() error\n");
<br> exit(-1);
<br> }
<p>while(1){
<br> sin_size=sizeof(struct sockaddr_in);
<br> if ((fd2 = accept(fd,(struct sockaddr *)&client,&sin_size))==-1){
/* calls accept() */
<br> printf("accept() error\n");
<br> exit(-1);
<br> }
<br>
<br> printf("You got a connection from %s\n",inet_ntoa(client.sin_addr)
); /* prints client's IP */
<br>
<br> send(fd2,"Welcome to my server.\n",22,0); /* send to the client
welcome message */
<br>
<br> close(fd2); /* close fd2 */
<br>}
<br>}
<p>/* <---- SOURCE CODE ENDS HERE ----> */
<br>
<br>
<p>Well lets try and compile shall we...
<br>
<p>Straight away we should clear the obvious problems, link to Winsock32.lib
and
<br>only include windows.h and stdio.h.
<p>Having done so we receive 2 errors, the first pertains to bzero which
we do not
<br>have in our little program so we are going to just remove the line
that contains
<br>it. Once we do so we now have only 1 error, woohoo!
<p>This error tells us that the function close() is not a valid identifier
which is
<br>what I said earlier, close() has been replaced by closesocket() in
windows so we
<br>change that as well to closesocket().
<p>We run this program and we recieve a socket error :(. But remember we
never entered
<br>WSAStartup() and WSACleanup() in this program so we have to do that
first and then
<br>our program will work :).
<p>If you run the program the command prompt should remain blank, just
leave the program
<br>as it is now and move onto the next section to figure out where to
go from here!!
<p>First of course here抯 the Windows code for the port ;).
<br>
<p>/* <---- SOURCE CODE STARTS HERE ----> */
<p>#include <stdio.h>
/* These are the usual header files */
<br>#include <windows.h>
<br>
<p>#define PORT 3550 /*
Port that will be opened */
<br>#define BACKLOG 2 /*
Number of allowed connections */
<p>main()
<br>{
<br> WSADATA wsdata;
<p> WSAStartup(0x0101,&wsdata);
<p> int fd, fd2; /* file
descriptors */
<br>
<p> struct sockaddr_in server; /* server's
address information */
<br> struct sockaddr_in client; /*
client's address information */
<p> int sin_size;
<br>
<p> if ((fd=socket(AF_INET, SOCK_STREAM, 0)) == -1 )
/* calls socket() */
<br> {
<br> printf("socket() error\n");
<br> exit(-1);
<br> }
<p> server.sin_family = AF_INET;
<br> server.sin_port
= htons(PORT); /* Remember htons() from "Conversions"
section? =) */
<br> server.sin_addr.s_addr = INADDR_ANY;
/* INADDR_ANY puts your IP address automatically */
<p>
<br> if(bind(fd,(struct sockaddr*)&server,sizeof(struct sockaddr))==-1)
/* calls bind() */
<br> {
<br> printf("bind() error\n");
<br> exit(-1);
<br> }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -