phần 4 các bài tập lập trình mạng các tuần

23
Bài 1: Sum Client // sumclient.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <WinSock2.h> SOCKADDR_IN serverAddr; SOCKET s; WSADATA wsaData; char* line = NULL; char* ret = NULL; int main(int argc, char* argv[]) { WSAStartup(MAKEWORD(2,2),&wsaData); serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(atoi(argv[2])); serverAddr.sin_addr.s_addr = inet_addr(argv[1]); s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); line = (char*)calloc(1024,1);

Upload: ngoc-vuquoc

Post on 17-Jan-2016

247 views

Category:

Documents


0 download

DESCRIPTION

dùng cho môn lập trình mạng : các ví dụ của thầy Vinh ,trường Bách khoa

TRANSCRIPT

Page 1: phần 4 Các bài tập lập trình mạng các tuần

Bài 1: Sum Client

// sumclient.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include <WinSock2.h>

SOCKADDR_IN serverAddr;

SOCKET s;

WSADATA wsaData;

char* line = NULL;

char* ret = NULL;

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

{

WSAStartup(MAKEWORD(2,2),&wsaData);

serverAddr.sin_family = AF_INET;

serverAddr.sin_port = htons(atoi(argv[2]));

serverAddr.sin_addr.s_addr = inet_addr(argv[1]);

s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

line = (char*)calloc(1024,1);

ret = (char*)calloc(1024,1);

if (connect(s,(sockaddr*)&serverAddr,sizeof(serverAddr)) == 0)

{

while (1)

Page 2: phần 4 Các bài tập lập trình mạng các tuần

{

printf("Nhap vao lenh: ");

gets(line);

send(s,line,strlen(line),0);

recv(s,ret,1024,0);

printf("%s\n",ret);

}

}else

{

printf("Cannot connect");

}

return 0;

}

Bài 2: Sum Server

// sumserver.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include <WinSock2.h>

typedef struct _CLIST

{

SOCKET c;

SOCKADDR_IN addr;

Page 3: phần 4 Các bài tập lập trình mạng các tuần

int addrlen;

char* buf;

char* ret;

_CLIST* next;

HANDLE hReady;

}CLIST;

SOCKADDR_IN serverAddr;

SOCKET s;

WSADATA wsaData;

DWORD ThreadID;

CLIST* pClients = NULL;

DWORD WINAPI SendingThread(LPVOID param)

{

CLIST* p = (CLIST*)param;

while (1)

{

WaitForSingleObject(p->hReady,INFINITE);

send(p->c,p->ret,strlen(p->ret),0);

Sleep(1);

}

return 0;

Page 4: phần 4 Các bài tập lập trình mạng các tuần

}

DWORD WINAPI RecvingThread(LPVOID param)

{

CLIST* p = (CLIST*)param;

p->buf = (char*)calloc(1024,1);

p->ret = (char*)calloc(1024,1);

while (1)

{

ResetEvent(p->hReady);

recv(p->c,p->buf,1024,0);

int a,b,c;

sscanf(p->buf,"%d%d",&a,&b);

c = a + b;

memset(p->ret,0,1024);

sprintf(p->ret,"%d\n",c);

SetEvent(p->hReady);

Sleep(1);

}

return 0;

}

DWORD WINAPI ListeningThread(LPVOID param)

Page 5: phần 4 Các bài tập lập trình mạng các tuần

{

pClients = (CLIST*)calloc(1,sizeof(CLIST));

while (1)

{

pClients->addrlen = sizeof(pClients->addr);

pClients->c = accept(s,(sockaddr*)&pClients->addr,&pClients->addrlen);

pClients->hReady = CreateEvent(NULL,TRUE,FALSE,NULL);

CreateThread(NULL,0,SendingThread,pClients,0,&ThreadID);

CreateThread(NULL,0,RecvingThread,pClients,0,&ThreadID);

pClients->next = (CLIST*)calloc(1,sizeof(CLIST));

pClients = pClients->next;

}

return 0;

}

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

{

WSAStartup(MAKEWORD(2,2),&wsaData);

serverAddr.sin_family = AF_INET;

serverAddr.sin_port = htons(atoi(argv[1]));

serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

Page 6: phần 4 Các bài tập lập trình mạng các tuần

bind(s,(sockaddr*)&serverAddr,sizeof(serverAddr));

listen(s,10);

WaitForSingleObject(CreateThread(NULL,0,ListeningThread,NULL,0,&ThreadID), INFINITE);

return 0;

}

Bài 3 : Simple Telnet Server

// SimpleTelnetServer.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include <string.h>

#include <malloc.h>

#include <WinSock2.h>

#define MAX_USER_COUNT 1024

#define MAX_STRING_LEN 1024

char** user = NULL;

char** pass = NULL;

int realcount = 0;

Page 7: phần 4 Các bài tập lập trình mạng các tuần

SOCKET s;

SOCKADDR_IN saddr;

SOCKET c[MAX_USER_COUNT];

SOCKADDR_IN caddr[MAX_USER_COUNT];

int clen[MAX_USER_COUNT];

int cid[MAX_USER_COUNT];

HANDLE cready[MAX_USER_COUNT];

int usercount = 0;

CRITICAL_SECTION criticalSection;

fd_set fdread;

fd_set fdwrite;

DWORD WINAPI ProcessingThread(LPVOID param)

{

char* buf = (char*)calloc(MAX_STRING_LEN,1);

while (1)

{

//Select

select(0, &fdread, &fdwrite, NULL, NULL);

//ISSET

for (int i = 0;i < usercount; i++)

{

if (FD_ISSET(c[i],&fdread))

Page 8: phần 4 Các bài tập lập trình mạng các tuần

{

//Receive data here

ResetEvent(cready[i]);

memset(buf,0,MAX_STRING_LEN);

recv(c[i],buf,MAX_STRING_LEN,0);

EnterCriticalSection(&criticalSection);

system(strcat(buf,">c:\\temp\\out.txt"));

LeaveCriticalSection(&criticalSection);

SetEvent(cready[i]);

}

if (FD_ISSET(c[i],&fdwrite))

{

WaitForSingleObject(cready[i],INFINITE);

EnterCriticalSection(&criticalSection);

//Write data here

FILE* f = fopen("c:\\temp\\out.txt","rt");

while (!feof(f))

{

memset(buf,0,MAX_STRING_LEN);

fgets(buf,MAX_STRING_LEN,f);

send(c[i],buf,strlen(buf),0);

}

fclose(f);

Page 9: phần 4 Các bài tập lập trình mạng các tuần

LeaveCriticalSection(&criticalSection);

}

}

}

return 0;

}

DWORD WINAPI LoginThread(LPVOID param)

{

int id = *((int*)param);

char* tmpuser = (char*)calloc(MAX_STRING_LEN,sizeof(char));

char* tmppass = (char*)calloc(MAX_STRING_LEN,sizeof(char));

char* userprompt = "User:";

char* passprompt = "Password:";

send(c[id], userprompt, strlen(userprompt),0); //Send a prompt to the client

recv(c[id],tmpuser,MAX_STRING_LEN,0); //Wait for the response

send(c[id], passprompt, strlen(passprompt),0); //Send another prompt

recv(c[id],tmppass,MAX_STRING_LEN,0); //Wait for the response

int i = 0;

for (i = 0;i < realcount;i++)

{

Page 10: phần 4 Các bài tập lập trình mạng các tuần

if (strcmp(user[i], tmpuser) == 0 && strcmp(pass[i], tmppass) == 0)

break; //Correct login information

}

if (i < realcount)

{

//Logged in successfully, start threads to communicate with the client

DWORD ThreadID;

//Add the accepted socket into the selection

FD_SET(c[id],&fdread);

FD_SET(c[id],&fdwrite);

//Processing thread

if (usercount == 1)

CreateThread(NULL,0,ProcessingThread,NULL,0,&ThreadID);

}else

{

//Wrong login information

char* invalid = "Invalid user/password";

send(c[id], invalid, strlen(invalid),0);

}

return 0;

}

Page 11: phần 4 Các bài tập lập trình mạng các tuần

DWORD WINAPI ListeningThread(LPVOID param)

{

DWORD ThreadID;

//Accepting connections here

while (1)

{

clen[usercount] = sizeof(SOCKADDR_IN);

c[usercount] = accept(s,(sockaddr*)&caddr[usercount],&clen[usercount]);

cid[usercount] = usercount;

cready[usercount] = CreateEvent(NULL,FALSE,FALSE,NULL);

//First start a login process by sending prompts and receiving user, pass

usercount += 1;

CreateThread(NULL,0,LoginThread,&cid[usercount],0,&ThreadID);

}

return 0;

}

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

{

if (argc <= 1)

{

Page 12: phần 4 Các bài tập lập trình mạng các tuần

printf("Invalid arguments\r\n");

return 0;

}

InitializeCriticalSection(&criticalSection);

user = (char**)calloc(MAX_USER_COUNT,sizeof(char*));

pass = (char**)calloc(MAX_USER_COUNT,sizeof(char*));

//Doc file user - password

FILE* f = fopen("users.txt","rt");

while (!feof(f))

{

user[realcount] = (char*)calloc(MAX_STRING_LEN,sizeof(char));

pass[realcount] = (char*)calloc(MAX_STRING_LEN,sizeof(char));

fscanf(f,"%s%s",user[realcount],pass[realcount]);

realcount += 1;

}

fclose(f);

WSADATA wsadata;

WSAStartup(MAKEWORD(2,2),&wsadata);

FD_ZERO(&fdwrite);

FD_ZERO(&fdread);

s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

saddr.sin_family = AF_INET;

Page 13: phần 4 Các bài tập lập trình mạng các tuần

saddr.sin_port = htons(atoi(argv[1]));

saddr.sin_addr.s_addr = htonl(INADDR_ANY);

bind(s,(sockaddr*)&saddr,sizeof(saddr));

listen(s,10);

DWORD ThreadID = 0;

WaitForSingleObject(CreateThread(NULL,0,ListeningThread,NULL,0,&ThreadID), INFINITE);

WSACleanup();

return 0;

}

Bài 4 : Completion Port

// CompletionPort.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include <WinSock2.h>

HANDLE CompletionPort;

WSADATA wsd;

SYSTEM_INFO SystemInfo;

SOCKADDR_IN InternetAddr;

SOCKET Listen;

Page 14: phần 4 Các bài tập lập trình mạng các tuần

struct MYOVERLAPPED

{

OVERLAPPED SystemOverlapped;

int MyStuff;

};

MYOVERLAPPED myoverlapped;

char buff[1024];

WSABUF databuff;

DWORD flags;

DWORD bytesReceived = 0;

typedef struct _PER_HANDLE_DATA

{

SOCKET Socket;

SOCKADDR_STORAGE ClientAddr;

// Other information useful to be associated with the handle

} PER_HANDLE_DATA, * LPPER_HANDLE_DATA;

DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)

{

// The requirements for the worker thread will be discussed later.

HANDLE CompletionPort = (HANDLE) CompletionPortID;

DWORD BytesTransferred;

Page 15: phần 4 Các bài tập lập trình mạng các tuần

LPOVERLAPPED Overlapped;

LPPER_HANDLE_DATA PerHandleData;

DWORD SendBytes, RecvBytes;

DWORD Flags;

BOOL ret;

MYOVERLAPPED* lpmyoverlapped;

while(TRUE)

{

// Wait for I/O to complete on any socket

// associated with the completion port

ret = GetQueuedCompletionStatus(CompletionPort,

&BytesTransferred,(LPDWORD)&PerHandleData,

(LPOVERLAPPED *) &lpmyoverlapped, INFINITE);

}

return 0;

}

int _tmain(int argc, _TCHAR* argv[])

{

WSADATA wsadata;

WSAStartup(MAKEWORD(2,2),&wsadata);

memset(&myoverlapped,0,sizeof(myoverlapped));

Page 16: phần 4 Các bài tập lập trình mạng các tuần

databuff.buf = buff;

databuff.len = 1024;

// Step 1:

// Create an I/O completion port

CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

// Step 2:

// Determine how many processors are on the system

GetSystemInfo(&SystemInfo);

// Step 3:

// Create worker threads based on the number of

// processors available on the system. For this

// simple case, we create one worker thread for each

// processor.

for(int i = 0; i < SystemInfo.dwNumberOfProcessors; i++)

{

HANDLE ThreadHandle;

// Create a server worker thread, and pass the

// completion port to the thread. NOTE: the

// ServerWorkerThread procedure is not defined

// in this listing.

Page 17: phần 4 Các bài tập lập trình mạng các tuần

ThreadHandle = CreateThread(NULL, 0,

ServerWorkerThread, CompletionPort,

0, NULL);

// Close the thread handle

CloseHandle(ThreadHandle);

}

// Step 4:

// Create a listening socket

Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);

InternetAddr.sin_family = AF_INET;

InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);

InternetAddr.sin_port = htons(5000);

bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr));

// Prepare socket for listening

listen(Listen, 5);

while(TRUE)

{

PER_HANDLE_DATA *PerHandleData=NULL;

Page 18: phần 4 Các bài tập lập trình mạng các tuần

SOCKADDR_IN saRemote;

SOCKET Accept;

int RemoteLen;

// Step 5:

// Accept connections and assign to the completion port

RemoteLen = sizeof(saRemote);

Accept = WSAAccept(Listen, (SOCKADDR *)&saRemote, &RemoteLen, NULL, NULL);

// Step 6:

// Create per-handle data information structure to associate with the socket

PerHandleData = (LPPER_HANDLE_DATA)

GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA));

printf("Socket number %d connected\n", Accept);

PerHandleData->Socket = Accept;

memcpy(&PerHandleData->ClientAddr, &saRemote, RemoteLen);

// Step 7:

// Associate the accepted socket with the completion port

CreateIoCompletionPort((HANDLE) Accept, CompletionPort, (DWORD) PerHandleData, 0);

// Step 8:

// Start processing I/O on the accepted socket.

// Post one or more WSASend() or WSARecv() calls

// on the socket using overlapped I/O.

Page 19: phần 4 Các bài tập lập trình mạng các tuần

myoverlapped.MyStuff = 10;

WSARecv(Accept, &databuff, 1, &bytesReceived, &flags, (LPOVERLAPPED)&myoverlapped, NULL);

}

return 0;

}