當前位置:首頁 » 編程語言 » c語言網路編程實例
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c語言網路編程實例

發布時間: 2023-01-21 00:23:52

Ⅰ 在windows下用c語言如何實現socket網路編程,需要用到哪些頭文件或者庫

需要用到的頭文件包含:

#include <winsock2.h>

#include <windows.h>

與Linux環境下socket編程相比,windows環境多了一個步驟:啟動或者初始化winsock庫

Winsock,一種標准API,一種網路編程介面,用於兩個或多個應用程序(或進程)之間通過網路進行數據通信。具有兩個版本:

Winsock 1:

Windows CE平台支持。

頭文件:WinSock.h

庫:wsock32.lib

Winsock 2:

部分平台如Windows CE貌似不支持。通過前綴WSA可以區別於Winsock 1版本。個別函數如WSAStartup、WSACleanup、WSARecvEx、WSAGetLastError都屬於Winsock 1.1規范的函數;

頭文件:WinSock2.h

庫:ws2_32.lib

mswsock.h用於編程擴展,使用時必須鏈接mswsock.dll

(1)c語言網路編程實例擴展閱讀

winsock庫的載入與卸載:

載入:int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);

載入成功,返回值為0。

WORD wVersionRequested:載入的winsock版本,使用宏MAKEWORD(x, y),x表示高位元組,y表示低位元組。然而使用時MAKEWORD(2, 2)。高位元組與低位元組相同~~

LPWSADATA lpWSAData:WSADATA結構的指針,傳入參數後,系統幫助我們填充版本信息。有興趣的可以看看結構體內容,不過基本用不著。

卸載:int WSACleanup(void);比起載入,卸載的函數真是輕松愉快。

Ⅱ tcp網路編程(C語言)

以下是兩個文件.client.c和server.c

server.c

client.c

運行效果如下

Ⅲ socket編程。怎麼實現數據包的轉發C語言版的。

我也不知道····只好復制一份···共同學習~~ 要寫網路程序就必須用Socket,這是程序員都知道的。而且,面試的時候,我們也會問對方會不會Socket編程?一般來說,很多人都會說,Socket編程基本就是listen,accept以及send,write等幾個基本的操作。是的,就跟常見的文件操作一樣,只要寫過就一定知道。對於網路編程,我們也言必稱TCP/IP,似乎其它網路協議已經不存在了。對於TCP/IP,我們還知道TCP和UDP,前者可以保證數據的正確和可靠性,後者則允許數據丟失。最後,我們還知道,在建立連接前,必須知道對方的IP地址和埠號。除此,普通的程序員就不會知道太多了,很多時候這些知識已經夠用了。最多,寫服務程序的時候,會使用多線程來處理並發訪問。我們還知道如下幾個事實:1。一個指定的埠號不能被多個程序共用。比如,如果IIS佔用了80埠,那麼Apache就不能也用80埠了。2。很多防火牆只允許特定目標埠的數據包通過。3。服務程序在listen某個埠並accept某個連接請求後,會生成一個新的socket來對該請求進行處理。於是,一個困惑了我很久的問題就產生了。如果一個socket創建後並與80埠綁定後,是否就意味著該socket佔用了80埠呢?如果是這樣的,那麼當其accept一個請求後,生成的新的socket到底使用的是什麼埠呢(我一直以為系統會默認給其分配一個空閑的埠號)?如果是一個空閑的埠,那一定不是80埠了,於是以後的TCP數據包的目標埠就不是80了--防火牆一定會組織其通過的!實際上,我們可以看到,防火牆並沒有阻止這樣的連接,而且這是最常見的連接請求和處理方式。我的不解就是,為什麼防火牆沒有阻止這樣的連接?它是如何判定那條連接是因為connet80埠而生成的?是不是TCP數據包里有什麼特別的標志?或者防火牆記住了什麼東西?後來,我又仔細研讀了TCP/IP的協議棧的原理,對很多概念有了更深刻的認識。比如,在TCP和UDP同屬於傳輸層,共同架設在IP層(網路層)之上。而IP層主要負責的是在節點之間(End to End)的數據包傳送,這里的節點是一台網路設備,比如計算機。因為IP層只負責把數據送到節點,而不能區分上面的不同應用,所以TCP和UDP協議在其基礎上加入了埠的信息,埠於是標識的是一個節點上的一個應用。除了增加埠信息,UPD協議基本就沒有對IP層的數據進行任何的處理了。而TCP協議還加入了更加復雜的傳輸控制,比如滑動的數據發送窗口(Slice Window),以及接收確認和重發機制,以達到數據的可靠傳送。不管應用層看到的是怎樣一個穩定的TCP數據流,下面傳送的都是一個個的IP數據包,需要由TCP協議來進行數據重組。所以,我有理由懷疑,防火牆並沒有足夠的信息判斷TCP數據包的更多信息,除了IP地址和埠號。而且,我們也看到,所謂的埠,是為了區分不同的應用的,以在不同的IP包來到的時候能夠正確轉發。TCP/IP只是一個協議棧,就像操作系統的運行機制一樣,必須要具體實現,同時還要提供對外的操作介面。就像操作系統會提供標準的編程介面,比如Win32編程介面一樣,TCP/IP也必須對外提供編程介面,這就是Socket編程介面--原來是這么回事啊!在Socket編程介面里,設計者提出了一個很重要的概念,那就是socket。這個socket跟文件句柄很相似,實際上在BSD系統里就是跟文件句柄一樣存放在一樣的進程句柄表裡。這個socket其實是一個序號,表示其在句柄表中的位置。這一點,我們已經見過很多了,比如文件句柄,窗口句柄等等。這些句柄,其實是代表了系統中的某些特定的對象,用於在各種函數中作為參數傳入,以對特定的對象進行操作--這其實是C語言的問題,在C++語言里,這個句柄其實就是this指針,實際就是對象指針啦。現在我們知道,socket跟TCP/IP並沒有必然的聯系。Socket編程介面在設計的時候,就希望也能適應其他的網路協議。所以,socket的出現只是可以更方便的使用TCP/IP協議棧而已,其對TCP/IP進行了抽象,形成了幾個最基本的函數介面。比如create,listen,accept,connect,read和write等等。現在我們明白,如果一個程序創建了

Ⅳ 求一個用C語言編寫的 subway_pay_system(地鐵售票系統)

linux下不是很熟,不過和windows下差不多吧,我會,不是很難。不過竟然都沒給分、、、

Ⅳ C語言 socket編程 TFTP伺服器與客戶端的實現

TFTP是一個傳輸文件的簡單協議,其於UDP協議而實現

socket是...我只能理解成是網路編程裡麵包含ip地址埠號的一個數據結構 具體我說不清楚

基礎肯定是要先了解udp ,先要掌握用udp接收和發送數據,
然後基於udp的數據發送接收再根據tftp協議的要求來寫程序

這個裡面有tftp的介紹
http://www.longen.org/S-Z/details-z/TFTPProtocol.htm

Ⅵ 關於用C語言開發一個簡單的區域網聊天軟體

可以,涉及到網路編程,windows下的不清楚 linux下的如果只實現文字傳遞 使用udp就可以。這些都有現成的函數的 比如sendto 幾十行代碼就能實現功能 ,你可以看看linux網路編程部分

Ⅶ 在windows下,如何用純C語言實現socket網路編程

mfc只是對socket進行了一些封裝,大部分人做網路編程都是用的原始的socket,比如如下介面都可以在c下進行調用
1.socket()
2.bind()
3.connect()
4.listen()
5.accept()
6.send() 和recv()
7.sendto() 和recvfrom()
8.close() 和shutdown()
9.getpeername()
10.gethostname()
這些介面是在Winsock2.h中定義的不是在mfc中定義的,你只需要包含Winsock2.h頭文件和Ws2_32.lib庫就可以了。

Ⅷ C語言與網路問題 高手進

ping命令是dos命令可以創建一個cmd進程,然後建立兩個管道用來得到結果 實現.

下面是一個網路編程的實例, Syn掃描器代碼,可以作為參考.
基本可以看為是 ping命令的實現
//getallIP.cpp
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
int main()
{
////////////////
// 初始化 Windows sockets API.
//
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(wVersionRequested, &wsaData)) {
printf("WSAStartup failed %s\n", WSAGetLastError());
return 0;
}

//////////////////
// 獲得主機名.
//
char hostname[256];
int res = gethostname(hostname, sizeof(hostname));
if (res != 0) {
printf("Error: %u\n", WSAGetLastError());
return 0;
}
printf("hostname=%s\n", hostname);
////////////////
// 根據主機名獲取主機信息.
//
hostent* pHostent = gethostbyname(hostname);
if (pHostent==NULL) {
printf("Error: %u\n", WSAGetLastError());
return 0;
}
//////////////////
// 解析返回的hostent信息.
//
hostent& he = *pHostent;
printf("name=%s\naliases=%s\naddrtype=%d\nlength=%d\n",
he.h_name, he.h_aliases, he.h_addrtype, he.h_length);

sockaddr_in sa;
//根據 he.h_addr_list[nAdapter]是否為空來獲取所有IP地址
for (int nAdapter=0; he.h_addr_list[nAdapter]; nAdapter++) {
memcpy ( &sa.sin_addr.s_addr, he.h_addr_list[nAdapter],he.h_length);
// 輸出機器的IP地址.
printf("Address [%d%]: %s\n",nAdapter, inet_ntoa(sa.sin_addr)); // 顯示地址串
}
//////////////////
// 終止 Windows sockets API
//
WSACleanup();
return 0;
}
//mstcpip.h
// Copyright (C) Microsoft Corporation, 1996-1999
#if _MSC_VER > 1000
#pragma once
#endif
/* Argument structure for SIO_KEEPALIVE_VALS */

struct tcp_keepalive {
u_long onoff;
u_long keepalivetime;
u_long keepaliveinterval;
};

// New WSAIoctl Options

#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#define SIO_RCVALL_MCAST _WSAIOW(IOC_VENDOR,2)
#define SIO_RCVALL_IGMPMCAST _WSAIOW(IOC_VENDOR,3)
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
#define SIO_ABSORB_RTRALERT _WSAIOW(IOC_VENDOR,5)
#define SIO_UCAST_IF _WSAIOW(IOC_VENDOR,6)
#define SIO_LIMIT_BROADCASTS _WSAIOW(IOC_VENDOR,7)
#define SIO_INDEX_BIND _WSAIOW(IOC_VENDOR,8)
#define SIO_INDEX_MCASTIF _WSAIOW(IOC_VENDOR,9)
#define SIO_INDEX_ADD_MCAST _WSAIOW(IOC_VENDOR,10)
#define SIO_INDEX_DEL_MCAST _WSAIOW(IOC_VENDOR,11)
//synscan.cpp
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

#include <time.h>
#include "mstcpip.h"
#pragma comment(lib,"ws2_32.lib")
#define SEQ 0x28376839

SOCKET sockRaw = INVALID_SOCKET,
sockListen = INVALID_SOCKET;
struct sockaddr_in dest;

BOOL ScanOK=FALSE;
char *DEST_HOST;
int DEST_PORT;
int DEST_PORTEND;
int play=0;
clock_t start,end;//程序運行的起始和結束時間
float costtime;//程序耗時

typedef struct _iphdr
{
unsigned char h_lenver; //4位首部長度+4位IP版本號
unsigned char tos; //8位服務類型TOS
unsigned short total_len; //16位總長度(位元組)
unsigned short ident; //16位標識
unsigned short frag_and_flags; //3位標志位
unsigned char ttl; //8位生存時間 TTL
unsigned char proto; //8位協議 (TCP, UDP 或其他)
unsigned short checksum; //16位IP首部校驗和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;

typedef struct _tcphdr //定義TCP首部
{
USHORT th_sport; //16位源埠
USHORT th_dport; //16位目的埠
unsigned int th_seq; //32位序列號
unsigned int th_ack; //32位確認號
unsigned char th_lenres; //4位首部長度/6位保留字
unsigned char th_flag; //6位標志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校驗和
USHORT th_urp; //16位緊急數據偏移量
}TCP_HEADER;

struct //定義TCP偽首部
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz;
char ptcl; //協議類型
unsigned short tcpl; //TCP長度
}psd_header;

//SOCK錯誤處理程序
void CheckSockError(int iErrorCode, char *pErrorMsg)
{
if(iErrorCode==SOCKET_ERROR)
{
printf("%s Error:%d\n", pErrorMsg, GetLastError());
closesocket(sockRaw);
ExitProcess(-1);
}

}

//計算檢驗和
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while (size > 1)
{
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size)
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}

//IP解包程序
bool DecodeIPHeader(char *buf, int bytes)
{
IP_HEADER *iphdr;
TCP_HEADER *tcphdr;
unsigned short iphdrlen;
iphdr = (IP_HEADER *)buf;
iphdrlen = sizeof(unsigned long) * (iphdr->h_lenver & 0xf);
tcphdr = (TCP_HEADER*)(buf + iphdrlen);
//是否來自目標IP
if(iphdr->sourceIP != dest.sin_addr.s_addr) return false;

//序列號是否正確
if((ntohl(tcphdr->th_ack) != (SEQ+1)) && (ntohl(tcphdr->th_ack) != SEQ)) return false;
//if(tcphdr->th_flag == 20)return true;
//SYN/ACK - 掃描到一個埠
if(tcphdr ->th_flag == 18)
{
printf("\t%d\t open \n",ntohs(tcphdr->th_sport));
return true;
}

return true;
}

void usage(void)
{
printf("\t===================SYN portscaner======================\n");
printf("\[email protected] 2004/7/6===========\n");
printf("\tusage: synscan DomainName[IP] StartPort-EndPort\n");
printf("\tExample: synscan www.163.com 1-139\n");
printf("\tExample: synscan 192.168.1.1 8000-9000\n");
}

DWORD WINAPI RecvThread(LPVOID para)//接收數據線程函數
{
int iErrorCode;
struct hostent *hp;
char RecvBuf[65535]={0};
sockListen = socket(AF_INET , SOCK_RAW , IPPROTO_IP);
CheckSockError(sockListen, "socket");

//設置IP頭操作選項
BOOL bOpt = true;
iErrorCode = setsockopt(sockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&bOpt,sizeof(bOpt));
CheckSockError(iErrorCode, "setsockopt()");

//獲得本地IP
SOCKADDR_IN sa;
unsigned char LocalName[256];

iErrorCode = gethostname((char*)LocalName,sizeof(LocalName)-1);
CheckSockError(iErrorCode, "gethostname()");
if((hp = gethostbyname((char*)LocalName)) == NULL)
{
CheckSockError(SOCKET_ERROR, "gethostbyname()");
}
memcpy(&sa.sin_addr.S_un.S_addr,hp->h_addr_list[1],hp->h_length);
sa.sin_family = AF_INET;
sa.sin_port = htons(7000);
iErrorCode = bind(sockListen, (PSOCKADDR)&sa, sizeof(sa));
CheckSockError(iErrorCode, "bind");

//設置SOCK_RAW為SIO_RCVALL,以便接收所有的IP包
DWORD dwBufferLen[10] ;
DWORD dwBufferInLen = 1 ;
DWORD dwBytesReturned = 0 ;
iErrorCode=WSAIoctl(sockListen, SIO_RCVALL,&dwBufferInLen, sizeof

(dwBufferInLen),&dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );
CheckSockError(iErrorCode, "Ioctl");
memset(RecvBuf, 0, sizeof(RecvBuf));
//接收數據
for(;;)
{

iErrorCode = recv(sockListen, RecvBuf, sizeof(RecvBuf), 0);
//CheckSockError(iErrorCode, "recv");
DecodeIPHeader(RecvBuf,iErrorCode) ;
}
if(ScanOK)
{
closesocket(sockListen);
return 0;
}
}

void playx(void) // 定義狀態提示函數
{
// 進度條
char *plays[12]=
{
" | ",
" / ",
" - ",
" \\ ",
" | ",
" / ",
" - ",
" \\ ",
" | ",
" / ",
" - ",
" \\ ",
};
printf(" =%s=\r", plays[play]);
play=(play==11)?0:play+1;
Sleep(2);
}

//主函數
int main(int argc,char **argv)
{
char *p;
if(argc!=3)
{
usage();
return 0;
}

p=argv[2];//處理埠參數
if(strstr(argv[2],"-"))
{ DEST_PORT=atoi(argv[2]);
for(;*p;)
if(*(p++)=='-')break;
DEST_PORTEND=atoi(p);

if(DEST_PORT<1 || DEST_PORTEND>65535)
{ printf("Port Error!\n");
return 0;
}

}

DEST_HOST=argv[1];

usage();

int iErrorCode;
int datasize;
struct hostent *hp;
IP_HEADER ip_header;
TCP_HEADER tcp_header;
char SendBuf[128]={0};

//初始化SOCKET
WSADATA wsaData;
iErrorCode = WSAStartup(MAKEWORD(2,2),&wsaData);
CheckSockError(iErrorCode, "WSAStartup()");
sockRaw = socket(AF_INET , SOCK_RAW , IPPROTO_IP);
CheckSockError(sockRaw, "socket()");
sockListen = socket(AF_INET , SOCK_RAW , IPPROTO_IP);
CheckSockError(sockListen, "socket");

//設置IP頭操作選項
BOOL bOpt = true;
iErrorCode = setsockopt(sockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&bOpt,sizeof(bOpt));
CheckSockError(iErrorCode, "setsockopt()");

//獲得本地IP
SOCKADDR_IN sa;
unsigned char LocalName[256];

iErrorCode = gethostname((char*)LocalName,sizeof(LocalName)-1);
CheckSockError(iErrorCode, "gethostname()");
if((hp = gethostbyname((char*)LocalName)) == NULL)
{
CheckSockError(SOCKET_ERROR, "gethostbyname()");
}

memcpy(&sa.sin_addr.S_un.S_addr,hp->h_addr_list[1],hp->h_length);
sa.sin_family = AF_INET;
sa.sin_port = htons(7000);
iErrorCode = bind(sockListen, (PSOCKADDR)&sa, sizeof(sa));
CheckSockError(iErrorCode, "bind");

//獲得目標主機IP
memset(&dest,0,sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(DEST_PORT);
if((dest.sin_addr.s_addr = inet_addr(DEST_HOST)) == INADDR_NONE)
{
if((hp = gethostbyname(DEST_HOST)) != NULL)
{
memcpy(&(dest.sin_addr),hp->h_addr_list[1],hp->h_length);
dest.sin_family = hp->h_addrtype;
printf("dest.sin_addr = %s\n",inet_ntoa(dest.sin_addr));
}
else
{
CheckSockError(SOCKET_ERROR, "gethostbyname()");
}
}

//開啟監聽線程
HANDLE Thread=CreateThread(NULL,0,RecvThread,0,0,0);

//填充IP首部
ip_header.h_lenver=(4<<4 | sizeof(ip_header)/sizeof(unsigned long));
//高四位IP版本號,低四位首部長度
ip_header.total_len=htons(sizeof(IP_HEADER)+sizeof(TCP_HEADER)); //16位總長度(位元組)
ip_header.ident=1; //16位標識
ip_header.frag_and_flags=0; //3位標志位
ip_header.ttl=128; //8位生存時間TTL
ip_header.proto=IPPROTO_TCP; //8位協議(TCP,UDP…)
ip_header.checksum=0; //16位IP首部校驗和
ip_header.sourceIP=sa.sin_addr.s_addr; //32位源IP地址
ip_header.destIP=dest.sin_addr.s_addr; //32位目的IP地址

//填充TCP首部
tcp_header.th_sport=htons(7000); //源埠號
tcp_header.th_lenres=(sizeof(TCP_HEADER)/4<<4|0); //TCP長度和保留位
tcp_header.th_win=htons(16384);

//填充TCP偽首部(用於計算校驗和,並不真正發送)
psd_header.saddr=ip_header.sourceIP;
psd_header.daddr=ip_header.destIP;
psd_header.mbz=0;
psd_header.ptcl=IPPROTO_TCP;
psd_header.tcpl=htons(sizeof(tcp_header));

Sleep(500);
printf("\n");
printf("Scaning %s\n",DEST_HOST);
start=clock();//開始計時

for(;DEST_PORT<DEST_PORTEND;DEST_PORT++)
{

playx();
tcp_header.th_dport=htons(DEST_PORT); //目的埠號
tcp_header.th_ack=0; //ACK序列號置為0
tcp_header.th_flag=2; //SYN 標志
tcp_header.th_seq=htonl(SEQ); //SYN序列號
tcp_header.th_urp=0; //偏移
tcp_header.th_sum=0; //校驗和
//計算TCP校驗和,計算校驗和時需要包括TCP pseudo header
memcpy(SendBuf,&psd_header,sizeof(psd_header));
memcpy(SendBuf+sizeof(psd_header),&tcp_header,sizeof(tcp_header));
tcp_header.th_sum=checksum((USHORT *)SendBuf,sizeof(psd_header)+sizeof(tcp_header));

//計算IP校驗和
memcpy(SendBuf,&ip_header,sizeof(ip_header));
memcpy(SendBuf+sizeof(ip_header),&tcp_header,sizeof(tcp_header));
memset(SendBuf+sizeof(ip_header)+sizeof(tcp_header),0,4);
datasize=sizeof(ip_header)+sizeof(tcp_header);
ip_header.checksum=checksum((USHORT *)SendBuf,datasize);

//填充發送緩沖區
memcpy(SendBuf,&ip_header,sizeof(ip_header));

//發送TCP報文
iErrorCode=sendto(sockRaw,SendBuf,datasize,0,(struct sockaddr*) &dest,
sizeof(dest));
CheckSockError(iErrorCode, "sendto()");
}
end=clock();//計時結束
ScanOK=TRUE;
printf("Closeing Thread.....\n");
WaitForSingleObject(Thread,5000);
CloseHandle(Thread);

costtime= (float)(end - start) / CLOCKS_PER_SEC; //轉換時間格式
printf("Cost time:%f Sec",costtime);//顯示耗時

//退出前清理
if(sockRaw != INVALID_SOCKET) closesocket(sockRaw);
WSACleanup();
return 0;
}

Ⅸ 網路編程C語言入門知識

c
語言
是高級語言,但由於它可以通過指針對內存進行訪問,具有了低級語言的特性,因此很多人也稱它是中級語言。按照內容來說C語言有自己的語言符號和語句規則,他有3種基本的結構:順序結構,選擇結構、循環結構。然後按照不同的需要通過用這三種結構的不同「組合」(當然不是拼湊那種簡單組合)就可以編出不同功能的程序了。

當然還有指針和結構體等其他一些內容,但編程強調的是演算法能力。演算法即是你要做一件事的步驟,在編程裡面體現的就是你要實現一個功能要知道編寫的內容有幾部分每一部分大概用什麼方法去實現。