1. 程式人生 > >《TCP/IP網路程式設計》第1章 筆記&程式碼&註釋

《TCP/IP網路程式設計》第1章 筆記&程式碼&註釋

註釋筆記在程式碼內:

伺服器:

//以下均在VS2015 WINDOWS平臺編譯並執行
//在Linux中 標頭檔案為:
//#incude<sys/socket.h>

//以下為服務端程式碼示例
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#pragma comment(lib, "ws2_32.lib")
#include<stdio.h>
#include<stdlib.h>
#include<WinSock2.h>
#define ser_port 8888 //埠號

void ErrorHandling(const char* message);
/*
argc為引數個數
argv[]為argc個引數,其中首個引數為程式的全名
*/
int main(int argc, char* argv[])
{
	WSADATA wsaData;
	SOCKET hServerSock, hClntSock;
	SOCKADDR_IN servAddr, clntAddr;
	argc = 1;
	int szClntAddr;
	char message[] = "Hello World!";
	/*
	if (argc != 2)
	{
	printf("Usage :%s <port>\n", argv[0]);
	exit(1);
	}*/
	/*
	Winsock的初始化
	MAKEWORD(2,2)返回值為WORD,WORD為套接字的版本資訊,這裡為主版本為2,副版本為2,返回0x0202;
	第二個引數為WSADATA型別引數的地址;
	*/
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		ErrorHandling("WSAStartup() error!");
	//建立套接字
	hServerSock = socket(PF_INET, SOCK_STREAM, 0);
	if (hServerSock == INVALID_SOCKET)
		ErrorHandling("socket() error!");

	memset(&servAddr, 0, sizeof(servAddr));
	servAddr.sin_family = AF_INET;
	servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servAddr.sin_port = htons(ser_port);

	//bind()為socker()函式建立的套接字分配IP地址和埠號
	if (bind(hServerSock, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
		ErrorHandling("bind() error!");
	/*
	listen() 伺服器等待連線資料 開始監聽
	*/
	if (listen(hServerSock, 5) == SOCKET_ERROR)
		ErrorHandling("listen() error!");

	/*
	accept()函式受理客戶端連線請求
	*/
	szClntAddr = sizeof(clntAddr);
	hClntSock = accept(hServerSock, (SOCKADDR*)&clntAddr, &szClntAddr);
	if (hClntSock == INVALID_SOCKET)
		ErrorHandling("accept() error!");

	/*
	send()向accept()連線的客戶端傳輸資料
	*/
	send(hClntSock, message, sizeof(message), 0);


	closesocket(hClntSock);
	closesocket(hServerSock);
	//終止前登出WSAStarup()初始化的套接字型檔
	WSACleanup();

	return 0;
}

void ErrorHandling(const char* message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

客戶端:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#pragma comment(lib, "ws2_32.lib")
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
void ErrorHandling(const char* message);

int main(int argc, char *argv[]) {
	WSADATA wsaData;
	SOCKET hSocket;
	SOCKADDR_IN servAddr;

	char message[30];
	int strlen;
	/*
	if (argc != 3) {
		printf("Usage: %s <IP> <port>\n", argv[0]);
		exit(1);
	}*/

	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		ErrorHandling("WSAStartup() error!");

	hSocket = socket(PF_INET, SOCK_STREAM, 0);
	if (hSocket == INVALID_SOCKET)
		ErrorHandling("socket() error!");

	memset(&servAddr, 0, sizeof(servAddr));
	servAddr.sin_family = AF_INET;
	servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");  //localhost,回送地址,本地測試用
	servAddr.sin_port = htons(8888);	//伺服器埠號

	//向伺服器傳送連結請求
	if (connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
		ErrorHandling("connect() error!");

	strlen = recv(hSocket, message, sizeof(message) - 1, 0);
	if (strlen == -1)
		ErrorHandling("read() error!");
	
	printf("Message from server:%s\n", message);
	closesocket(hSocket);
	WSACleanup();
	getchar();
	return 0;
}

void ErrorHandling(const char * message) {
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

注:

執行環境:windows 10 ,VisualStudio 2015

標頭檔案#include<winsock2.h>若初次執行請在配置屬性-輸入-附加依賴項中空白處直接寫入 ws2_32.lib 以連線ws2_32.lib庫

請先執行伺服器程式碼後再執行客戶端程式碼

程式碼:

https://github.com/ChristmasError/TCP-IP-Network-programming