導航:首頁 > 編程語言 > 基本套接字編程

基本套接字編程

發布時間:2023-03-20 18:43:07

① 關於用c語言進行套接字編程

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
int server_sockfd;//伺服器端套接字
int client_sockfd;//客戶端套接字
int len;
struct sockaddr_in my_addr; //伺服器網路地址結構體
struct sockaddr_in remote_addr; //客戶端網路地址結構體
int sin_size;
char buf[BUFSIZ]; //數據傳送的緩沖區
memset(&my_addr,0,sizeof(my_addr)); //數據初始化--清零
my_addr.sin_family=AF_INET; //設置為IP通信
my_addr.sin_addr.s_addr=INADDR_ANY;//伺服器IP地址--允許連接到所有本地地址上
my_addr.sin_port=htons(8000); //伺服器埠號

/*創建伺服器端套接字--IPv4協議,面向連接通信,TCP協議*/
if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)
{
perror("socket");
return 1;
}

/*將套接字綁定到伺服器的網路地址上*/
if (bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)
{
perror("bind");
return 1;
}

/*監聽連接請求--監聽隊列長度為5*/
listen(server_sockfd,5);

sin_size=sizeof(struct sockaddr_in);

/*等待客戶端連接請求到達*/
if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0)
{
perror("accept");
return 1;
}
printf("accept client %s/n",inet_ntoa(remote_addr.sin_addr));
len=send(client_sockfd,"Welcome to my server/n",21,0);//發送歡迎信息

/*接收客戶端的數據並將其發送給客戶端--recv返回接收到的位元組數,send返回發送的位元組數*/
while((len=recv(client_sockfd,buf,BUFSIZ,0))>0))
{
buf[len]='/0';
printf("%s/n",buf);
if(send(client_sockfd,buf,len,0)<0)
{
perror("write");
return 1;
}
}
close(client_sockfd);
close(server_sockfd);
return 0;
}

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
int client_sockfd;
int len;
struct sockaddr_in remote_addr; //伺服器端網路地址結構體
char buf[BUFSIZ]; //數據傳送的緩沖區
memset(&remote_addr,0,sizeof(remote_addr)); //數據初始化--清零
remote_addr.sin_family=AF_INET; //設置為IP通信
remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//伺服器IP地址
remote_addr.sin_port=htons(8000); //伺服器埠號

/*創建客戶端套接字--IPv4協議,面向連接通信,TCP協議*/
if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)
{
perror("socket");
return 1;
}

/*將套接字綁定到伺服器的網路地址上*/
if(connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0)
{
perror("connect");
return 1;
}
printf("connected to server/n");
len=recv(client_sockfd,buf,BUFSIZ,0);//接收伺服器端信息
buf[len]='/0';
printf("%s",buf); //列印伺服器端信息

/*循環的發送接收信息並列印接收信息--recv返回接收到的位元組數,send返回發送的位元組數*/
while(1)
{
printf("Enter string to send:");
scanf("%s",buf);
if(!strcmp(buf,"quit")
break;
len=send(client_sockfd,buf,strlen(buf),0);
len=recv(client_sockfd,buf,BUFSIZ,0);
buf[len]='/0';
printf("received:%s/n",buf);
}
close(client_sockfd);//關閉套接字
return 0;
}

② c語言 多線程套接字編程

你ip的初始值是多少?
有沒有重定向過標准輸入?
另一個線程是否也阻塞在讀標准輸入上?

③ 數據報套接字編程步驟

數據報套接字編程的順序就是按照正常的數字文件需求來編寫。
編程時首先按照操作需求編寫初級代碼,然後再完成代碼的升級編寫。

④ 在javasocket網路編程中,開發基於udp協議的程序使用的套接字有哪些

Socket套接字,是由系統提供用於網路通信的技術(操作系統給應用程序提供的一組API叫做Socket API),是基於TCP/IP協議的網路通信的基本操作單元。基於Socket套接字的網路程序開發就是網路編程。

socket可以視為是應用層和傳輸層之間的通信橋梁;
傳輸層的核心協議有兩種:TCP,UDP;socket API也有對應的兩組,由於TCP和UDP協議差別很大,因此,這兩組API差別也挺大。

分類:
Socket套接字主要針對傳輸層協議劃分為如下三類:

流套接字:使用傳輸層TCP協議
TCP,即Transmission Control Protocol(傳輸控制協議),傳輸層協議;
TCP的特點:

有連接:像打電話,得先接通,才能交互數據;
可靠傳輸:傳輸過程中,發送方知道接收方有沒有收到數據.(打電話就是可靠傳輸);
面向位元組流:以位元組為單位進行傳輸.(非常類似於文件操作中的位元組流);
全雙工:一條鏈路,雙向通信;
有接收緩沖區,也有發送緩沖區。
大小不限
對於位元組流來說,可以簡單的理解為,傳輸數據是基於IO流,流式數據的特徵就是在IO流沒有關閉的情況下,是無邊界的數據,可以多次發送,也可以分開多次接收。

數據報套接字:使用傳輸層UDP協議
UDP,即User Datagram Protocol(用戶數據報協議),傳輸層協議。
UDP的特點:

無連接:像發微信,不需要接通,直接就能發數據;
不可靠傳輸:傳輸過程中,發送方不知道接收方有沒有收到數據.(發微信就是不可靠傳輸);
面向數據報:以數據報為單位進行傳輸(一個數據報都會明確大小)一次發送/接收必須是一個完整的數據報,不能是半個,也不能是一個半;
全雙工:一條鏈路,雙向通信;
有接收緩沖區,無發送緩沖區;
大小受限:一次最多傳輸64k;
對於數據報來說,可以簡單的理解為,傳輸數據是一塊一塊的,發送一塊數據假如100個位元組,必須一次發送,接收也必須一次接收100個位元組,而不能分100次,每次接收1個位元組。

原始套接字
原始套接字用於自定義傳輸層協議,用於讀寫內核沒有處理的IP協議數據。

二、UDP數據報套接字編程
UDPSocket中,主要涉及到兩類:DatagramSocket、DatagramPacket;

DatagramSocket API
DatagramSocket 創建了一個UDP版本的Socket對象,用於發送和接收UDP數據報,代表著操作系統中的一個socket文件,(操作系統實現的功能–>)代表著網卡硬體設備的抽象體現。

DatagramSocket 構造方法:

方法簽名 方法說明
DatagramSocket() 創建一個UDP數據報套接字的Socket,綁定到本機任意一個隨機埠(一般用於客戶端)
DatagramSocket(int port) 創建一個UDP數據報套接字的Socket,綁定到本機指定的埠(一般用於服務端)
DatagramSocket 方法:

方法簽名 方法說明
void receive(DatagramPacket p) 從此套接字接收數據報(如果沒有接收到數據報,該方法會阻塞等待)
void send(DatagramPacket p) 從此套接字發送數據報包(不會阻塞等待,直接發送)
void close() 關閉此數據報套接字
DatagramPacket API
代表了一個UDP數據報,是UDP Socket發送和接收的數據報,每次發送/接收數據報,都是在傳輸一個DatagramPacket對象。

DatagramPacket 構造方法:

方法簽名 方法說明
DatagramPacket(byte[] buf, int length) 構造一個DatagramPacket以用來接收數據報,接收的數據保存在位元組數組(第一個參數buf)中,接收指定長度(第二個參數length)
DatagramPacket(byte[] buf, int offset, int length,SocketAddress address) 構造一個DatagramPacket以用來發送數據報,發送的數據為位元組數組(第一個參數buf)中,從0到指定長度(第二個參數length)。address指定目的主機的IP和埠號
DatagramPacket 方法:

方法簽名 方法說明
InetAddress getAddress() 從接收的數據報中,獲取發送端主機IP地址;或從發送的數據報中,獲取接收端主機IP地址
int getPort() 從接收的數據報中,獲取發送端主機的埠號;或從發送的數據報中,獲取接收端主機埠號
byte[] getData() 獲取數據報中的數據
構造UDP發送的數據報時,需要傳入 SocketAddress ,該對象可以使用 InetSocketAddress 來創建。

InetSocketAddress API
InetSocketAddress ( SocketAddress 的子類 )構造方法:

方法簽名 方法說明
InetSocketAddress(InetAddress addr, int port) 創建一個Socket地址,包含IP地址和埠號
示例1:寫一個簡單的客戶端服務程序,回顯服務(EchoSever)
在這里插入圖片描述
構建Socket對象有很多失敗的可能:

埠號已經被佔用,同一個主機的兩個程序不能有相同的埠號(這就好比兩個人不能擁有相同的電話號碼);
此處,多個進程不能綁定同一個埠號,但是一個進程可以綁定多個埠,(這就好比一個人可以擁有多個手機號),一個進程可以創建多個Socket對象,每個Socket都綁定自己的埠。
每個進程能夠打開的文件個數是有上限的,如果進程之間已經打開了很多文件,就可能導致此時的Socket文件不能順利打開;
在這里插入圖片描述
這個長度不一定是1024,假設這里的UDP數據最長是1024,實際的數據可能不夠1024.

在這里插入圖片描述
這里的參數不再是一個空的位元組數組了,response是剛才根據請求計算的得到的響應,是非空的,DatagramPacket 裡面的數據就是String response的數據。

response.getBytes().length:這里拿到的是位元組數組的長度(位元組的個數),而response.length得到的是字元的長度。

五元組
一次通信是由5個核心信息描述的:源IP、 源埠、 目的IP、 目的埠、 協議類型。

站在客戶端角度:

源IP:本機IP;
源埠:系統分配的埠;
目的IP:伺服器的IP;
目的埠:伺服器的埠;
協議類型:TCP;
站在伺服器的角度:

源IP:伺服器程序本機的IP;
源埠:伺服器綁定的埠(此處手動指定了9090);
目的IP:包含在收到的數據報中(客戶端的IP);
目的埠:包含在收到的數據報中(客戶端的埠);
協議類型:UDP;

⑤ C語言套接字編程實現通信

我知道Linux的,但估計你想要的不是這個。
另:套接字就是 Socket,是網路連接的一種方式,基於TCP、UDP之類的

⑥ 入門級:怎麼使用C#進行套接字編程

1.TCP流式套接字的編程步驟
在使用之前須鏈接芹森庫函數:工程->設置->Link->輸入ws2_32.lib,OK!
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//創建套接字(socket)。

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//轉換Unsigned short為網路位元組序的格式
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
客戶端代碼如下:
#include <Winsock2.h>
#include <stdio.h>

void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );載入套接字型檔
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup()( );
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);創建套接字(socket)。

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));向伺服器發出連接請求(connect)。

char recvBuf[100];和伺服器端進行通信(send/recv)。
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
send(sockClient,"銀首返This is lisi",strlen("This is lisi"鋒飢)+1,0);

closesocket(sockClient);關閉套接字。
WSACleanup()();//必須調用這個函數清除參數
}

⑦ 面向連接和無連接方式套接字編程有什麼不同

1、關於使用套接字編程的一些基本概念
二元組的定義:<K,R>
三元組的定義:<D,F,A>
五元組的定義:<V,O,G,M,S>
V是值的集合,O是操作的集合,G是構成名字的文法,M是存儲的集合,S是從G能構成的名字 幾個到M的映射.

(a)半相關與全相關
半相關:在網路中用一個三元組可以在全局唯芹凱一標志一個進程: (協議,本地地址,本地埠號)這樣一個三元組,叫做一個半相關(half-association),它指定連接的每半部分。
全相關:一個完整的網間進程通信需要由兩個進程組成,並且只能使用同一種高層協議。也就是說,不可能通信的一端用TCP協議,而另一端用UDP協議。因此一個完整的網間通信需要一個五元組來標識:(協議,本地地址,本地埠號,遠地地址,遠地埠號)這樣一個五元組,叫做一個相關(association),即兩個協議相同的半相關才能組合成一個合適的相關,或完全指定組成一連接。

(b)TCP/IP協議的地址結構為:
struct sockaddr_in
{
short sin_family; /*AF_INET*/
u_short sin_port; /*16位埠號,網路位元組順序*/
struct in_addr sin_addr; /*32位IP地址,網路位元組順序*/
char sin_zero[8]; /*保留*/
}

(c)套接字大飢類型
TCP/IP的socket提供下列三種類型套接字。

流式套接字(SOCK_STREAM):提供了一個面向連接、可靠的數據傳輸服務,數據無差錯、無重復地發送,且按發送順序接收。內設流量控制,避免數據流超限;數據被看作是位元組流,無長度限制。文件傳送協議(FTP)即使用流式套接字。

數據報式套接字(SOCK_DGRAM):提供了一個無連接服務。數據包以獨立包形式被發送,不提供無錯保證,數據可能丟失或重復,並且接收順序混亂。網路文件系統(NFS)使用數據報式套接字。

原始式套接字(SOCK_RAW):該介面允許對較低層協議,如IP、ICMP直接訪問。常用於檢驗新的協議實現或訪問現有服務中配置的新設備。

(d)基本套接字系統調用
為了更好地說明套接字 編程原理,下面給出幾個基本套接字系統調用說明。
(1)創建套接字──socket()
應用程序在使用套接字前,首先必須擁有一個套接字,系統調用socket()向應用程序提供創建套接字的手段,其調用格式如下:

SOCKET socket(int af, int type, int protocol);

該調用要接收三個參數:af、type、protocol。參數af指定通信發生的區域,UNIX系統支持的地址族有:AF_UNIX、AF_INET、AF_NS等,而DOS、WINDOWS中僅支持AF_INET,它是網際網區域。因此,地址族與協議族相同。參數type描述要建立的套接字的類型。參數protocol 說明該套接字使用的特定協議,如果調用者不希望特別指定使用的協議,則置為0,使用默認的連接模式。根據嫌仿喚這三個參數建立一個套接字,並將相應的資源分配給它, 同時返回一個整型套接字型大小。因此,socket()系統調用實際上指定了相關五元組中的「協議」這一元。

(2)指定本地地址──bind()
當一個套接字用socket()創建後,存在一個名字空間(地址族),但它沒有被命名。bind()將套接字地址(包括本地主機地址和本地埠地址)與所創建的套接字型大小聯系起來,即將名字賦予套接字,以指定本地半相關。其調用格式如下:

int bind(SOCKET s, const struct sockaddr FAR * name, int namelen);

參數 s 是由 socket() 調用返回的並且未作連接的套接字描述符(套接字型大小)。參數name是賦給套接字s的本地地址(名字),其長度可變,結構隨通信域的不同而不同。namelen表明了name的長度。 如果沒有錯誤發生,bind()返回0。否則返回值SOCKET_ERROR。 地址在建立套接字通信過程中起著重要作用,作為一個網路應用程序設計者對套接字地址結構必須有明確認識。

(3)建立套接字連接──connect()與accept()
這兩個系統調用用於完成一個完整相關的建立,其中connect()用於建立連接。無連接的套接字進程也可以調用connect(),但這時在進程之間沒有實際的報文交換,調用將從本地操作系統直接返回。這樣做的優點是程序員不必為每一數據指定目的地址,而且如果收到的一個數據報,其目的埠未與任何套接字建立「連接」,便能判斷該埠不可操作。而accept()用於使伺服器等待來自某客戶進程的實際連接。 connect()的調用格式如下:

int connect(SOCKET s,const struct sockaddr FAR * name,int namelen);

參數s是欲建立連接的本地套接字描述符。參數name指出說明對方套接字地址結構的指針。對方套接字地址長度由namelen說明。 如果沒有錯誤發生,connect()返回0。否則返回值SOCKET_ERROR。在面向連接的協議中,該調用導致本地系統和外部系統之間連接實際建立。 由於地址族總被包含在套接字地址結構的前兩個位元組中,並通過socket()調用與某個協議族相關。因此bind()和connect()無須協議作為參數。 accept()的調用格式如下:

SOCKET accept(SOCKET s,struct sockaddr FAR* addr,int FAR* addrlen);

參數s為本地套接字描述符,在用做accept() 調用的參數前應該先調用過listen()。addr 指向客戶方套接字地址結構的指針, 用來接收連接實體的地址。addr的確切格式由套接字創建時建立的地址族決定。addrlen 為客戶方套接字地址的長度(位元組數)。如果沒有錯誤發生,accept()返回一個SOCKET類型的值,表示接收到的套接字的描述符。否則返回值INVALID_SOCKET。 accept()用於面向連接伺服器。參數addr和addrlen 存放客戶方的地址信息。調用前,參數addr 指向一個初始值為空的地址結構,而 addrlen 的初始值為0; 調用accept() 後,伺服器等待從編號為s的套接字上接受客戶連接請求,而連接請求是由客戶方的connect()調用發出的。當有連接請求到達時,accept()調用將請求連接隊列上的第一個客戶方套接字地址及長度放入addr和addrlen,並創建一個與s有相同特性的新套接字型大小。新的套接字可用於處理伺服器並發請求。

四個套接字系統調用,socket()、bind()、connect()、accept(),可以完成一個完全五元相關的建立。socket()指定五元組中的協議元,它的用法與是否為客戶或伺服器、是否面向連接無關。bind()指定五元組中的本地二元,即本地主機地址和埠號,其用法與是否面向連接有關:在伺服器方,無論是否面向連接,均要調用 bind() ;在客戶方,若採用面向連接,則可以不調用bind(),而通過connect()自動完成。若採用無連接,客戶方必須使用bind()以獲得一個唯一的地址。 以上討論僅對客戶/伺服器模式而言,實際上套接字的使用是非常靈活的,唯一需遵循的原則是進程通信之前,必須建立完整的相關。

(4)監聽連接──listen()
此調用用於面向連接伺服器,表明它願意接收連接。listen()需在accept()之前調用,其調用格式如下:

int listen(SOCKET s, int backlog);

參數s標識一個本地已建立、尚未連接的套接字型大小, 伺服器願意從它上面接收請求。 backlog 表示請求連接隊列的最大長度, 用於限制排隊請求的個數,目前允許的最大值為5。如果沒有錯誤發生,listen()返回0。否則它返回SOCKET_ERROR。 listen()在執行調用過程中可為沒有調用過bind() 的套接字s完成所必須的連接,並建立長度為backlog的請求連接隊列。 調用listen()是伺服器接收一個連接請求的四個步驟中的第三步。它在調用socket() 分配一個流套接字,且調用bind()給s賦於一個名字之後調用,而且一定要在accept()之前調用。

(5)數據傳輸──send()與recv()
當一個連接建立以後,就可以傳輸數據了。常用的系統調用有 send() 和recv()。 send() 調用用於在參數s指定的已連接的數據報或流套接字上發送輸出數據,格式如下:

int send(SOCKET s, const char FAR *buf, int len, int flags);

參數s為已連接的本地套接字描述符。buf 指向存有發送數據的緩沖區的指針,其長度由 len 指定。flags 指定傳輸控制方式,如是否發送帶外數據等。如果沒有錯誤發生,send()返回總共發送的位元組數。否則它返回SOCKET_ERROR。 recv()調用用於在參數s指定的已連接的數據報或流套接字上接收輸入數據,格式如下:

int recv(SOCKET s, char FAR *buf, int len, int flags);

參數s 為已連接的套接字描述符。buf指向接收輸入數據緩沖區的指針,其長度由len 指定。flags 指定傳輸控制方式,如是否接收帶外數據等。如果沒有錯誤發生,recv()返回總共接收的位元組數。如果連接被關閉,返回0。否則它返回SOCKET_ERROR。

(6)輸入/輸出多路復用──select()
select()調用用來檢測一個或多個套接字的狀態。對每一個套接字來說,這個調用可以請求讀、寫或錯誤狀態方面的信息。請求給定狀態的套接字集合由一個fd_set結構指示。在返回時,此結構被更新,以反映那些滿足特定條件的套接字的子集,同時, select()調用返回滿足條件的套接字的數目,其調用格式如下:

int select(int nfds, fd_set FAR * readfds, fd_set FAR * writefds,fd_set FAR * exceptfds, const struct timeval FAR * timeout);

參數nfds指明被檢查的套接字描述符的值域,此變數一般被忽略。 參數readfds指向要做讀檢測的套接字描述符集合的指針,調用者希望從中讀取數據。 參數 writefds 指向要做寫檢測的套接字描述符集合的指針。exceptfds指向要檢測是否出錯的套接字描述符集合的指針。timeout指向select()函數等待的最大時間,如果設為NULL則為阻塞操作。select()返回包含在fd_set結構中已准備好的套接字描述符的總數目,或者是發生錯誤則返回SOCKET_ERROR。

(7)關閉套接字──closesocket()

閱讀全文

與基本套接字編程相關的資料

熱點內容
中國電影票房排行榜實時票房貓眼 瀏覽:287
收母收姐妹 瀏覽:378
一男兩女後面兩女懷孕的番號 瀏覽:555
不需要會員就能看電視劇的網站 瀏覽:427
朝鮮古裝三及片 瀏覽:113
手機怎麼設置不解壓 瀏覽:110
崇石是誰演的 瀏覽:827
免費影視觀看網站入口 瀏覽:877
為什麼伺服器會出現很多藍屏 瀏覽:34
三國種馬收了何皇後 瀏覽:344
思甜APP怎麼樣 瀏覽:525
床戲美國 瀏覽:763
醉猴拳電影在線觀看 瀏覽:832
程序員在線教育 瀏覽:986
有部電影人可以穿牆 瀏覽:656
丁巴度電影有哪些 瀏覽:49
歐文電影叫什麼名字 瀏覽:498
雲伺服器操作過程 瀏覽:689
python自動提取參數 瀏覽:161
linuxjetty查看版本 瀏覽:689