is thread the one that OS is aware of?

Thread Testing (The Old New Story)

    A. First Edition

    All are started with a simple naive doubt: are threads true kernel threads? In other words, is "pthread" which is a library

    supported at OS level? Or is OS aware of its existence? Why do I ask? Because in OS lecture, professor talks about there

    are three kinds of threads: kernel level, application level, mixed level. Kernel level means that they are truly system

    threads and OS actually scheduling them like processes. Application level means OS knows nothing about them and it is up

    to application to do scheduling. One typical example is java threads which is totally under JVM control. (Isn't???)

    The mixed model is quite complicated and I only remember that there are a kind of mapping between application threads and

    kernel threads. When the number of them is not matched, it is quite a complex model.

    Anyway this seems to be a truly simple, common-sense question and probably most of guys from computer science would laugh

    at me why I have such simple doubt. Yes, why do I have such simple doubt?

    The reason is that I don't trust "library-provider" can hack deep into OS level unless OS support them instead. The testing

    result seems that Linux guys indeed like "POSIX" threads and give them true support such that they are kernel threads and

    not like "library". (Then why cannot we call them system API about threads?)

    B.The problem

Sometimes I just don't understand something which seems so natural and so common. But I don't really believe I am as retard

as it seems to be. Taking TCP protocol as an example, is it implemented at level of driver or is TCP protocol done by

network adaptor? But I really doubt it. Anyway I can explain to myself like this. The so-called physical-level and

link-level is done by network adaptor, even including some routing level job. And just like file IO, these kind of

operations are also using interrupt model. That is, asynchronizing I/O. And since these kind of operation is much slower

than those "transmission control protocol"(TCP) work, CPU can switch between other more computation-oriented job. In other

words, network communication is indeed a sort of I/O. (This sounds like bullshit and many people would just ask why not?)

¡¡

C.The idea of program

So, whatever I am doing is just confirming "pthread" is truly OS-aware thread implementation and network is truly an I/O

operation. (This really sounds silly.)

And the experiment is suggested by Mr. W who considers these are common-sense. However, I simply cannot accept one fact in

Linux: Among 128 syscall there is nothing about thread and how can "pthread" which is just a library manage scheduling of

Linux native threads? The similar question comes up when I am surprised to see there is no accurate timer call in Linux

syscall and some library call like "gettimeofday", "nanotimer"(??) can give as accurate as microsecond. How can they do

that? Alex argues that 128 syscall would not be sufficient for OS to expose all its functionality. Hence some functionality

is actually exposed by some property or data for user to read by themself, instead of making a function call. This sounds

reasonable and I also accept at that time. But for operation as complicated as scheduling, can you do that by reading and

setting some properties?

Of course everything can be figured out by reading kernel source code of Linux. However, I am not up to that or keen to

that level. Maybe in future.

    D.The major functions

    The testing is very trivial. There are always two threads. One is I/O and the other is a light threads with counting.

    Suppose the I/O thread is blocked, if OS is aware of another thread, it will be run for counting. One slight minor purpose

    is to coding for a simple socket framework for my future using with all error messages. This is really a typist job.

    E.Further improvement

    What is the problem? First, when I try to retrieve windows thread ID, I always get an exception at end of program. It seems

    some resources are not properly released. Or more probably the address I supplied for "CreateThread" parameter is a temporay

    variable and the thread cannot find it when it exits.

    Secondly I observe that "File Handle" in windows cannot be shared between threads. You have to re-open the same file instead

    just use the same handle among threads. This seems reasonable because handle probably pointing to some file status which is

    not designed for multiple concurrent access.

    Third, I just download some sample code of UDP from internet. And for quite long I just figure out he must be wrong with

    basic concept that UDP socket doesn't need "listen". Say, "listen" is for connected communication only.

    ¡¡

    So, what do I get? 1. a simple template for socket with full error messages. 2. a linux version with those tedious "header"

    files including. (This is really mad. How chaotic is Linux head files are! If you are working with kernel or driver, the

    header files are another nightmare.)

    ¡¡

    F.File listing

    1. server.cpp (TCP server)

    ¡¡

    1. singleThread.cpp

    2. socket.cpp

    3. singleThread.h

    ¡¡

    ¡¡

    1. server.cpp (Linux version)

    ¡¡

    ¡¡

    ¡¡

    file name: server.cpp

    //
    // Server.cpp
    //

    #include <stdio.h>
    #include <winsock2.h>
    #include "..\\singleThread.h"

    #pragma comment(lib, "ws2_32.lib")

    int errCode;

    SOCKET serverSocket;
    char buffer[BufferSize+1];
    int recvSize;

    void initialize()
    {

    	WSADATA wsaData;
    	HOSTENT* pHostEnt;
    	char hostName[32];
    	sockaddr_in sa;
    	if (errCode=WSAStartup(0x0202,&wsaData))
    	{
    		switch(errCode)
    		{
    		case WSASYSNOTREADY:
    			printf("Indicates that the underlying network subsystem is not ready for network\
    				communication. \n");
    			break;
    		case WSAVERNOTSUPPORTED:
    			printf("The version of Windows Sockets support requested is not provided by this\
    				particular Windows Sockets implementation. \n");
    			break;
    		case WSAEINPROGRESS:
    			printf("A blocking Windows Sockets 1.1 operation is in progress. \n");
    			break;
    		case WSAEPROCLIM:
    			printf("Limit on the number of tasks supported by the Windows Sockets \
    				implementation has been reached. ");
    			break;
    		case WSAEFAULT:
    			printf("The lpWSAData is not a valid pointer. \n");
    			break;
    		default:
    			printf("unknown error\n");
    			break;
    		}
    	}
    	if (gethostname(hostName, 32)==SOCKET_ERROR)
    	{
    		errCode=WSAGetLastError();
    		switch (errCode)
    		{
    		case WSAEFAULT:
    			printf("The name parameter is not a valid part of the user address space, or \
    				the buffer size specified by namelen parameter is too small to hold the \
    				complete host name. \n");
    			break;
    		case WSANOTINITIALISED:
    			printf("A successful WSAStartup call must occur before using this function. \n");
    			break;
    		case WSAENETDOWN:
    			printf("The network subsystem has failed. \n");
    			break;
    		case WSAEINPROGRESS:
    			printf("A blocking Windows Sockets 1.1 call is in progress, or the service \
    				provider is still processing a callback function. \n");
    			break;
    		default:
    			printf("unknown error\n");
    			break;
    		}
    	}

    	pHostEnt=gethostbyname(hostName);
    	if (pHostEnt==NULL)
    	{
    		errCode=WSAGetLastError();
    		switch (errCode)
    		{
    		case WSANOTINITIALISED:
    			printf("A successful WSAStartup call must occur before using this function. \n");
    			break;
    		case WSAENETDOWN:
    			printf("The network subsystem has failed. \n");
    			break;
    		case WSAHOST_NOT_FOUND:
    			printf("Authoritative answer host not found. \n");
    			break;
    		case WSATRY_AGAIN:
    			printf("Nonauthoritative host not found, or server failure. \n");
    			break;
    		case WSANO_RECOVERY:
    			printf("A nonrecoverable error occurred. \n");
    			break;
    		case WSANO_DATA:
    			printf("Valid name, no data record of requested type. \n");
    			break;
    		case WSAEINPROGRESS:
    			printf("A blocking Windows Sockets 1.1 call is in progress, or the service \
    				provider is still processing a callback function. \n");
    			break;
    		case WSAEFAULT:
    			printf("The name parameter is not a valid part of the user address space. \n");
    			break;
    		case WSAEINTR:
    			printf("A blocking Windows Socket 1.1 call was canceled through \n");
    			break;
    		default:
    			printf("unknown error\n");
    			break;
    		}
    	}

    	if ((serverSocket=socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET)
    	{
    		errCode=WSAGetLastError();
    		switch (errCode)
    		{
    		case WSANOTINITIALISED:
    			printf("A successful WSAStartup call must occur before using this function. \n");
    			break;
    		case WSAENETDOWN:
    			printf("The network subsystem or the associated service provider has failed. \n");
    			break;
    		case WSAEAFNOSUPPORT:
    			printf("The specified address family is not supported. \n");
    			break;
    		case WSAEINPROGRESS:
    			printf("A blocking Windows Sockets 1.1 call is in progress, or the service \
    				provider is still processing a callback function. \n");
    			break;
    		case WSAEMFILE:
    			printf("No more socket descriptors are available. \n");
    			break;
    		case WSAENOBUFS:
    			printf("No buffer space is available. The socket cannot be created. \n");
    			break;
    		case WSAEPROTONOSUPPORT:
    			printf("The specified protocol is not supported. \n");
    			break;
    		case WSAEPROTOTYPE:
    			printf("The specified protocol is the wrong type for this socket. \n");
    			break;
    		case WSAESOCKTNOSUPPORT:
    			printf("The specified socket type is not supported in this address family. \n");
    			break;
    		}
    	}

    	memset(&sa, 0, sizeof(sockaddr));
    	sa.sin_family = AF_INET;
    	sa.sin_port = htons(5000);
    	sa.sin_addr.s_addr = htonl(INADDR_ANY);

    	//Bind the server port

    	if (bind(serverSocket,(LPSOCKADDR)&sa,sizeof(sa)) == SOCKET_ERROR)
    	{
    		errCode=WSAGetLastError();
    		switch (errCode)
    		{
    		case WSANOTINITIALISED:
    			printf("A successful WSAStartup call must occur before using this function. \n");
    			break;
    		case WSAENETDOWN:
    			printf("The network subsystem has failed. \n");
    			break;
    		case WSAEACCES:
    			printf("WSAEACCES\n");
    			break;
    		case WSAEADDRINUSE:
    			printf("A process on the machine is already bound to the same fully-qualified \
    				address and the socket has not been marked to allow address reuse with \
    				SO_REUSEADDR. For example, the IP address and port are bound in \
    				the af_inet case). (See the SO_REUSEADDR socket option under setsockopt.) \n");
    			break;
    		case WSAEADDRNOTAVAIL:
    			printf("The specified address is not a valid address for this machine. \n");
    			break;
    		case WSAEFAULT:
    			printf("The name or namelen parameter is not a valid part of the user address \
    				space, the namelen parameter is too small, the name parameter contains an \
    				incorrect address format for the associated address family, or the first\
    				two bytes of the memory block specified by name does not match the address \
    				family associated with the socket descriptor s. \n");
    			break;
    		case WSAEINPROGRESS:
    			printf("A blocking Windows Sockets 1.1 call is in progress, or the service provider\
    				is still processing a callback function. \n");
    			break;
    		case WSAEINVAL:
    			printf("The socket is already bound to an address. \n");
    			break;
    		case WSAENOBUFS:
    			printf("Not enough buffers available, too many connections. \n");
    			break;
    		case WSAENOTSOCK:
    			printf("The descriptor is not a socket. \n");
    			break;
    		}

    	}
    }

    void singleWorking()
    {
    	while (true)
    	{
    		recvSize=recv(serverSocket, buffer, BufferSize, 0);
    		if (recvSize==SOCKET_ERROR)
    		{
    			errCode=WSAGetLastError();
    			switch (errCode)
    			{
    			case WSANOTINITIALISED:
    				printf("A successful WSAStartup call must occur before using this \
    					function. \n");
    				break;
    			case WSAENETDOWN:
    				printf("The network subsystem has failed. \n");
    				break;
    			case WSAEFAULT:
    				printf("The buf or from parameters are not part of the user address space,\
    					or the fromlen parameter is too small to accommodate the peer \
    					address. \n");
    				break;
    			case WSAEINTR:
    				printf("The (blocking) call was canceled through WSACancelBlockingCall.\n");
    				break;
    			case WSAEINPROGRESS:
    				printf("A blocking Windows Sockets 1.1 call is in progress, or the \
    					service provider is still processing a callback function. \n");
    				break;
    			case WSAEINVAL:
    				printf("The socket has not been bound with bind, or an unknown flag\
    					was specified, or MSG_OOB was specified for a socket with \
    					SO_OOBINLINE enabled, or (for byte stream-style sockets only) \
    					len was zero or negative. \n");
    				break;
    			case WSAEISCONN:
    				printf("The socket is connected. This function is not permitted with\
    					a connected socket, whether the socket is connection-oriented \
    					or connectionless. \n");
    				break;
    			case WSAENETRESET:
    				printf("The connection has been broken due to the keep-alive \
    					activity detecting a failure while the operation was in progress. \n");
    				break;
    			case WSAENOTSOCK:
    				printf("The descriptor is not a socket. \n");
    				break;
    			case WSAEOPNOTSUPP:
    				printf("MSG_OOB was specified, but the socket is not stream-style\
    					such as type SOCK_STREAM, OOB data is not supported in the \
    					communication domain associated with this socket, or the socket\
    					is unidirectional and supports only send operations. \n");
    				break;
    			case WSAESHUTDOWN:
    				printf("The socket has been shut down; it is not possible to recvfrom \
    					on a socket after shutdown has been invoked with how set to\
    					SD_RECEIVE or SD_BOTH. \n");
    				break;
    			case WSAEWOULDBLOCK:
    				printf("The socket is marked as nonblocking and the recvfrom operation\
    					would block. \n");
    				break;
    			case WSAEMSGSIZE:
    				printf("The message was too large to fit into the specified buffer\
    					and was truncated. \n");
    				break;
    			case WSAETIMEDOUT:
    				printf("The connection has been dropped, because of a network \
    					failure or because the system on the other end went down without \
    					notice. \n");
    				break;
    			case WSAECONNRESET:
    				printf("The virtual circuit was reset by the remote side executing \
    					a hard or abortive close. The application should close the socket\
    					as it is no longer usable. On a UPD-datagram socket this error \
    					would indicate that a previous send operation resulted in an ICMP \
    					\"Port Unreachable\" message.\n");
    				break;
    			}
    		}
    		else
    		{
    			//buffer[recvSize]='\0';
    			//printf("recv %d bytes of '%s'\n", recvSize, buffer);
    		}

    	}

    }

    void working()
    {
    	fd_set readfds;
    	int infds=1, outfds;

    	SOCKADDR fromAddr;
    	int fromSize=sizeof(sockaddr);

    	while (true)
    	{
    		FD_ZERO(&readfds);
    		FD_SET(serverSocket, &readfds);
    		if ((outfds=select(infds, &readfds, NULL, NULL, NULL))==SOCKET_ERROR)
    		{
    			errCode=WSAGetLastError();
    			switch (errCode)
    			{
    			case WSANOTINITIALISED:
    				printf("A successful WSAStartup call must occur before using this function. \n");
    				break;
    			case WSAEFAULT:
    				printf("The Windows Sockets implementation was unable to allocate needed \
    					resources for its internal operations, or the readfds, writefds, exceptfds,\
    					or timeval parameters are not part of the user address space. \n");
    				break;
    			case WSAENETDOWN:
    				printf("The network subsystem has failed. \n");
    				break;
    			case WSAEINVAL:
    				printf("The time-out value is not valid, or all three descriptor parameters \
    					were NULL. \n");
    				break;
    			case WSAEINTR:
    				printf("A blocking Windows Socket 1.1 call was canceled through \
    					WSACancelBlockingCall. \n");
    				break;
    			case WSAEINPROGRESS:
    				printf("A blocking Windows Sockets 1.1 call is in progress, or the service \
    					provider is still processing a callback function. \n");
    				break;
    			case WSAENOTSOCK:
    				printf("One of the descriptor sets contains an entry that is not a socket. \n");
    				break;
    			default:
    				printf("unknown error\n");
    				break;
    			}
    		}
    		else
    		{
    			if (FD_ISSET(serverSocket,&readfds))
    			{
    				recvSize=recvfrom(serverSocket, buffer, BufferSize, 0, &fromAddr, &fromSize);
    				if (recvSize==SOCKET_ERROR)
    				{
    					errCode=WSAGetLastError();
    					switch (errCode)
    					{
    					case WSANOTINITIALISED:
    						printf("A successful WSAStartup call must occur before using this \
    							function. \n");
    						break;
    					case WSAENETDOWN:
    						printf("The network subsystem has failed. \n");
    						break;
    					case WSAEFAULT:
    						printf("The buf or from parameters are not part of the user address space,\
    							or the fromlen parameter is too small to accommodate the peer \
    							address. \n");
    						break;
    					case WSAEINTR:
    						printf("The (blocking) call was canceled through WSACancelBlockingCall.\n");
    						break;
    					case WSAEINPROGRESS:
    						printf("A blocking Windows Sockets 1.1 call is in progress, or the \
    							service provider is still processing a callback function. \n");
    						break;
    					case WSAEINVAL:
    						printf("The socket has not been bound with bind, or an unknown flag\
    							was specified, or MSG_OOB was specified for a socket with \
    							SO_OOBINLINE enabled, or (for byte stream-style sockets only) \
    							len was zero or negative. \n");
    						break;
    					case WSAEISCONN:
    						printf("The socket is connected. This function is not permitted with\
    							a connected socket, whether the socket is connection-oriented \
    							or connectionless. \n");
    						break;
    					case WSAENETRESET:
    						printf("The connection has been broken due to the keep-alive \
    							activity detecting a failure while the operation was in progress. \n");
    						break;
    					case WSAENOTSOCK:
    						printf("The descriptor is not a socket. \n");
    						break;
    					case WSAEOPNOTSUPP:
    						printf("MSG_OOB was specified, but the socket is not stream-style\
    							such as type SOCK_STREAM, OOB data is not supported in the \
    							communication domain associated with this socket, or the socket\
    							is unidirectional and supports only send operations. \n");
    						break;
    					case WSAESHUTDOWN:
    						printf("The socket has been shut down; it is not possible to recvfrom \
    							on a socket after shutdown has been invoked with how set to\
    							SD_RECEIVE or SD_BOTH. \n");
    						break;
    					case WSAEWOULDBLOCK:
    						printf("The socket is marked as nonblocking and the recvfrom operation\
    							would block. \n");
    						break;
    					case WSAEMSGSIZE:
    						printf("The message was too large to fit into the specified buffer\
    							and was truncated. \n");
    						break;
    					case WSAETIMEDOUT:
    						printf("The connection has been dropped, because of a network \
    							failure or because the system on the other end went down without \
    							notice. \n");
    						break;
    					case WSAECONNRESET:
    						printf("The virtual circuit was reset by the remote side executing \
    							a hard or abortive close. The application should close the socket\
    							as it is no longer usable. On a UPD-datagram socket this error \
    							would indicate that a previous send operation resulted in an ICMP \
    							\"Port Unreachable\" message.\n");
    						break;
    					}
    				}
    				else
    				{
    					printf("recv %d bytes of %s\n", buffer);
    				}

    			}
    		}
    	}
    }

    ///////////////////////////////////////////////////////////////////////////////

    file name: singleThread.cpp

    #include <windows.h>
    #include <stdio.h>
    #include "singleThread.h"

    bool canFinish=false;
    bool canStart=false;
    //bool canExit=false;
    int count=0;

    const char* fileName="myoutput.txt";
    HANDLE fileHandle;
    extern char buffer[BufferSize+1];

    extern void working();
    extern void initialize();
    extern bool canStop;

    DWORD WINAPI socketProc(LPVOID param)
    {
    	initialize();
    	canStart=canStop=true;
    	working();
    	canFinish=true;

    	return 0;
    }

    DWORD WINAPI fileProc(LPVOID param)
    {
    	DWORD size;

    	HANDLE myHandle;
    	//CopyHandle(
    	myHandle=CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
    		FILE_ATTRIBUTE_NORMAL, NULL);

    	if (myHandle==NULL)
    	{
    		printf("open read file failed\n");
    		printf("error =%d\n", GetLastError());
    	}
    	canStart=true;
    	if (!ReadFile(myHandle, buffer, BufferSize, &size, NULL))
    	{
    		printf("read file failed\n");
    		printf("error =%d\n", GetLastError());
    	}
    	/*
    	if (size==0)
    	{
    		printf("read file failed\n");
    		printf("error =%d\n", GetLastError());
    	}
    */

    	canFinish=true;
    	CloseHandle(myHandle);
    	return 0;
    }

    DWORD WINAPI countProc(LPVOID param)
    {
    	while (!canStart)
    	{
    		Sleep(0);
    	}
    	while (!canFinish)
    	{
    		count++;
    		Sleep(0);
    	}
    	return 0;
    }

    int main()
    {
    	//DWORD threadID[2];
    	DWORD size;
    	HANDLE firstHandle, secondHandle;

    	fileHandle=CreateFile(fileName, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ, NULL,
    		CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    	if (!WriteFile(fileHandle, buffer, BufferSize, &size, NULL))
    	{
    		printf("write file failed\n");
    		printf("error =%d\n", GetLastError());
    		exit(2);
    	}
    	if (size==0)
    	{
    		printf("write file failed\n");
    		printf("error =%d\n", GetLastError());
    		exit(2);
    	}

    	SetEndOfFile(fileHandle);
    	CloseHandle(fileHandle);

    	//firstHandle=CreateThread(NULL, 0, fileProc, NULL, CREATE_SUSPENDED, &threadID[0]);
    	//secondHandle=CreateThread(NULL, 0, countProc, NULL, CREATE_SUSPENDED, &threadID[2]);
    	//firstHandle=CreateThread(NULL, 0, fileProc, &size, 0, NULL);
    	firstHandle=CreateThread(NULL, 0, socketProc, &size, 0, NULL);
    	secondHandle=CreateThread(NULL, 0, countProc, &size, 0, NULL);

    	if (firstHandle==NULL||secondHandle==NULL)
    	{
    		printf("failed create thread\n");
    		printf("error =%d\n", GetLastError());
    		exit(1);
    	}

    	//ResumeThread(firstHandle);
    	//ResumeThread(secondHandle);

    	WaitForSingleObject(firstHandle,INFINITE);
    	WaitForSingleObject(secondHandle,INFINITE);
    	//CloseHandle(firstHandle);
    	//CloseHandle(secondHandle);
    	/*
    	if (!CloseHandle(fileHandle))
    	{
    		printf("close file failed\n");
    		printf("error =%d\n", GetLastError());

    	}
    	*/
    	/*
    	if (!DeleteFile(fileName))
    	{
    		printf("delete file failed\n");
    		printf("error =%d\n", GetLastError());
    	}
    	*/
    	printf("count=%d\n", count);

    	return 0;
    }

    file name: socket.cpp

    //
    // Server.cpp
    //

    #include <stdio.h>
    #include <winsock2.h>
    #include "singleThread.h"

    #pragma comment(lib, "ws2_32.lib")

    int errCode;

    SOCKET clientSocket;

    char buffer[BufferSize];
    int sendSize;

    bool canStop=false;

    sockaddr_in sendAddr;

    void initialize()
    {
    	WSADATA wsaData;
    	HOSTENT* pHostEnt;
    	char hostName[32];

    	if (errCode=WSAStartup(0x0202,&wsaData))
    	{
    		switch(errCode)
    		{
    		case WSASYSNOTREADY:
    			printf("Indicates that the underlying network subsystem is not ready for network\
    				communication. \n");
    			break;
    		case WSAVERNOTSUPPORTED:
    			printf("The version of Windows Sockets support requested is not provided by this\
    				particular Windows Sockets implementation. \n");
    			break;
    		case WSAEINPROGRESS:
    			printf("A blocking Windows Sockets 1.1 operation is in progress. \n");
    			break;
    		case WSAEPROCLIM:
    			printf("Limit on the number of tasks supported by the Windows Sockets \
    				implementation has been reached. ");
    			break;
    		case WSAEFAULT:
    			printf("The lpWSAData is not a valid pointer. \n");
    			break;
    		default:
    			printf("unknown error\n");
    			break;
    		}
    	}
    	if (gethostname(hostName, 32)==SOCKET_ERROR)
    	{
    		errCode=WSAGetLastError();
    		switch (errCode)
    		{
    		case WSAEFAULT:
    			printf("The name parameter is not a valid part of the user address space, or \
    				the buffer size specified by namelen parameter is too small to hold the \
    				complete host name. \n");
    			break;
    		case WSANOTINITIALISED:
    			printf("A successful WSAStartup call must occur before using this function. \n");
    			break;
    		case WSAENETDOWN:
    			printf("The network subsystem has failed. \n");
    			break;
    		case WSAEINPROGRESS:
    			printf("A blocking Windows Sockets 1.1 call is in progress, or the service \
    				provider is still processing a callback function. \n");
    			break;
    		default:
    			printf("unknown error\n");
    			break;
    		}
    	}

    	pHostEnt=gethostbyname(hostName);
    	if (pHostEnt==NULL)
    	{
    		errCode=WSAGetLastError();
    		switch (errCode)
    		{
    		case WSANOTINITIALISED:
    			printf("A successful WSAStartup call must occur before using this function. \n");
    			break;
    		case WSAENETDOWN:
    			printf("The network subsystem has failed. \n");
    			break;
    		case WSAHOST_NOT_FOUND:
    			printf("Authoritative answer host not found. \n");
    			break;
    		case WSATRY_AGAIN:
    			printf("Nonauthoritative host not found, or server failure. \n");
    			break;
    		case WSANO_RECOVERY:
    			printf("A nonrecoverable error occurred. \n");
    			break;
    		case WSANO_DATA:
    			printf("Valid name, no data record of requested type. \n");
    			break;
    		case WSAEINPROGRESS:
    			printf("A blocking Windows Sockets 1.1 call is in progress, or the service \
    				provider is still processing a callback function. \n");
    			break;
    		case WSAEFAULT:
    			printf("The name parameter is not a valid part of the user address space. \n");
    			break;
    		case WSAEINTR:
    			printf("A blocking Windows Socket 1.1 call was canceled through \n");
    			break;
    		default:
    			printf("unknown error\n");
    			break;
    		}
    	}

    	if ((clientSocket=socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET)
    	{
    		errCode=WSAGetLastError();
    		switch (errCode)
    		{
    		case WSANOTINITIALISED:
    			printf("A successful WSAStartup call must occur before using this function. \n");
    			break;
    		case WSAENETDOWN:
    			printf("The network subsystem or the associated service provider has failed. \n");
    			break;
    		case WSAEAFNOSUPPORT:
    			printf("The specified address family is not supported. \n");
    			break;
    		case WSAEINPROGRESS:
    			printf("A blocking Windows Sockets 1.1 call is in progress, or the service \
    				provider is still processing a callback function. \n");
    			break;
    		case WSAEMFILE:
    			printf("No more socket descriptors are available. \n");
    			break;
    		case WSAENOBUFS:
    			printf("No buffer space is available. The socket cannot be created. \n");
    			break;
    		case WSAEPROTONOSUPPORT:
    			printf("The specified protocol is not supported. \n");
    			break;
    		case WSAEPROTOTYPE:
    			printf("The specified protocol is the wrong type for this socket. \n");
    			break;
    		case WSAESOCKTNOSUPPORT:
    			printf("The specified socket type is not supported in this address family. \n");
    			break;
    		default:
    			printf("unknown error\n");
    			break;
    		}
    	}
    	memset(&sendAddr, 0, sizeof(sockaddr));
    	sendAddr.sin_family = AF_INET;
    	sendAddr.sin_port = htons(5000);
    	memcpy(&sendAddr.sin_addr.s_addr , pHostEnt->h_addr_list[0], pHostEnt->h_length);

    	//Bind the server port

    }

    void working()
    {

    	do
    	{
    		sendSize=sendto(clientSocket, buffer, BufferSize, 0, (sockaddr*)&sendAddr,
    			sizeof(sockaddr_in));

    		if (sendSize==SOCKET_ERROR)
    		{
    			errCode=WSAGetLastError();
    			switch (errCode)
    			{
    			case WSANOTINITIALISED:
    				printf("A successful WSAStartup call must occur before using this function. \n");
    				break;
    			case WSAENETDOWN:
    				printf("The network subsystem has failed. \n");
    				break;
    			case WSAEACCES:
    				printf("The requested address is a broadcast address, but the appropriate \
    					flag was not set. Call setsockopt with the SO_BROADCAST parameter to \
    					allow the use of the broadcast address. \n");
    				break;
    			case WSAEINTR:
    				printf("A blocking Windows Sockets 1.1 call was canceled through \
    					WSACancelBlockingCall. \n");
    				break;
    			case WSAEINPROGRESS:
    				printf("A blocking Windows Sockets 1.1 call is in progress, or the service\
    					provider is still processing a callback function. \n");
    				break;
    			case WSAEFAULT:
    				printf("The buf parameter is not completely contained in a valid part of the\
    					user address space. \n");
    				break;
    			case WSAENETRESET:
    				printf("The connection has been broken due to the keep-alive activity \
    					detecting a failure while the operation was in progress. \n");
    				break;
    			case WSAENOBUFS:
    				printf("No buffer space is available. \n");
    				break;
    			case WSAENOTCONN:
    				printf("The socket is not connected. \n");
    				break;
    			case WSAENOTSOCK:
    				printf("The descriptor is not a socket. \n");
    				break;
    			case WSAEOPNOTSUPP:
    				printf("MSG_OOB was specified, but the socket is not stream-style such as \
    					type SOCK_STREAM, OOB data is not supported in the communication domain\
    					associated with this socket, or the socket is unidirectional and supports\
    					only receive operations. \n");
    				break;
    			case WSAESHUTDOWN:
    				printf("The socket has been shut down; it is not possible to send on a socket\
    					after shutdown has been invoked with how set to SD_SEND or SD_BOTH. \n");
    				break;
    			case WSAEWOULDBLOCK:
    				printf("The socket is marked as nonblocking and the requested operation would\
    					block. \n");
    				break;
    			case WSAEMSGSIZE:
    				printf("The socket is message oriented, and the message is larger than the\
    					maximum supported by the underlying transport. \n");
    				break;
    			case WSAEHOSTUNREACH:
    				printf("The remote host cannot be reached from this host at this time. \n");
    				break;
    			case WSAEINVAL:
    				printf("The socket has not been bound with bind, or an unknown flag was \
    					specified, or MSG_OOB was specified for a socket with SO_OOBINLINE \
    					enabled. \n");
    				break;
    			case WSAECONNABORTED:
    				printf("The virtual circuit was terminated due to a time-out or other failure.\
    					The application should close the socket as it is no longer usable. \n");
    				break;
    			case WSAECONNRESET:
    				printf("The virtual circuit was reset by the remote side executing a hard or\
    					abortive close. For UPD sockets, the remote host was unable to deliver\
    					a previously sent UDP datagram and responded with a \"Port Unreachable\"\
    					ICMP packet. The application should close the socket as it is no longer\
    					usable. \n");
    				break;
    			case WSAETIMEDOUT:
    				printf("The connection has been dropped, because of a network failure or\
    					because the system on the other end went down without notice. \n");
    				break;
    			default:
    				printf("unknown error\n");
    				break;
    			}

    		}
    	}
    	while (!canStop);
    }

    ¡¡

    file name: singleThread.h //(retard)

    const int BufferSize=32*1024;

    ¡¡

    file name: server.cpp (Linux version, I just download some sample for reference and the guy is a noob like me

    who doesn't understand UDP doesn't even need a "listen" which is for TCP or connected communication.Sigh...)

    //
    // Server.cpp
    //
    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <string.h>
    #include <errno.h>
    #include <ctype.h>

    extern int errno;

    const int BufferSize=1024*16;

    int serverSocket;
    char buffer[BufferSize+1];
    int recvSize;
    int sendSize;
    const unsigned short Port=5000;

    void initialize()
    {
    	struct sockaddr_in sa;
    	if ((serverSocket=socket(AF_INET,SOCK_DGRAM,0))<0)
    	{
    		printf("error of socket\n");
    	}

    	memset(&sa, 0, sizeof(sockaddr_in));
    	sa.sin_family = AF_INET;
    	sa.sin_port = htons(Port);
    	sa.sin_addr.s_addr = htonl(INADDR_ANY);

    	//Bind the server port

    	if (bind(serverSocket,(sockaddr*)&sa,sizeof(sa)) <0)
    	{
    		printf("error bind\n");
    	}
    /*
    	if (listen(serverSocket, 1)<0)
    	{
    		printf("listen error\n");
    		switch(errno)
    		{
    		case EADDRINUSE:
    			printf("Another socket is already listening on the same port.\n");
    			break;
    		case EBADF:
    			printf("The argument s is not a valid descriptor.\n");
    			break;
    		case ENOTSOCK:
    			printf("The argument s is not a socket.\n");
    			break;
    		case EOPNOTSUPP:
    			printf("The socket is not of a type that supports the listen  operation.\n");
    			break;
    		default:
    			printf("unknown error\n");
    			break;
    		}
    		exit(errno);
    	}
    */
    }

    void singleWorking()
    {
    	sockaddr_in fromAddr;
    	socklen_t addrSize=sizeof(sockaddr_in);
    	while (true)
    	{
    		if ((recvSize=recvfrom(serverSocket, buffer, BufferSize,0, (sockaddr*)&fromAddr,
    			&addrSize))<0)
    		{
    			printf("recvfrom error\n");
    		}
    		else
    		{

    			for (int i=0; i<recvSize; i++)
    			{
    				buffer[i]=toupper(buffer[i]);
    			}
    			if ((sendSize=sendto(serverSocket, buffer, recvSize, 0, (sockaddr*)&fromAddr,
    			addrSize))<0)
    			{
    				printf("sendto error\n");
    			}
    		}

    	}

    }

    int main()
    {
    	initialize();
    	singleWorking();

    	return 0;

    }

    ¡¡

¡¡

¡¡