socket編程-ag真人国际官网
a. socket編程資料
我選第一個題目,這是伺服器端,用c#實現的(vs2005):
using system;
using system.collections.generic;
using system.text;
using system.net;
using system.threading;
using system.net.sockets;
namespace connetworkserver
{
class program
{
static void main(string[] args)
{
socket client;
socket serversocket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.ip);
byte[] addbyte = { 127, 0, 0, 1 };
ipendpoint add = new ipendpoint(new ipaddress(addbyte), 5050);
serversocket.bind(add);
serversocket.listen(3);
while (true)
{
thread.sleep(100);
if ((client = serversocket.accept()) != null)
{
console.writeline("連接上...發送數據....");
byte[] message = { 49, 50, 51, 52, 53, 54, 0 };
client.send(message);
console.writeline("結束.")
client.close();
break;
}
}
}
}
}
這是客戶端:
using system;
using system.collections.generic;
using system.text;
using system.net;
using system.threading;
using system.net.sockets;
namespace connetworkclient
{
class program
{
static void main(string[] args)
{
socket server = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.ip);
byte[] addbyte = { 127, 0, 0, 1 };
server.connect(new ipaddress(addbyte), 5050);
byte[] buffer = new byte[255];
if (server.receive(buffer) > 0)
{
console.writeline("連接上...");
console.writeline("從伺服器接收數據...");
console.writeline(buffer.tostring());
console.writeline("連接斷開...");
server.disconnect(false);
server.close();
}
}
}
}
b. socket編程
#include
#include
#include
#include
#pragma comment (lib,"ws2_32.lib")
int main (int argc, char *argv[])
{
int iportfrom,iportto;
int testsocket;
int iopenedport = 0;
struct sockaddr_in target_addr;
wsadata wsadata;
word wversionrequested=makeword(1,1);
if (argc <= 3)
{
cout << "使用格式 : " << argv[0] << " 主機ip地址 開始埠號 結束埠號\n" << endl;
exit(1);
}
if (atoi (argv[2]) > atoi (argv[3]))
{
cout << "錯誤!開始埠號必須小於結束埠號" << endl;
exit(1);
}
else
{
if (wsastartup (wversionrequested , &wsadata) )
{
cout << "連接socket庫失敗,請檢查版本號是否為1.1\n" << endl;
exit(1);
}
iportfrom=atoi (argv[2]);
iportto=atoi (argv[3]);
for (int i=iportfrom; i <= iportto; i )
{
cout << "正在建立socket................................" << endl;
if ((testsocket=socket (af_inet,sock_stream,0) ) == invalid_socket)
{
cout << "socket建立失敗!" << endl;
exit(0);
}
target_addr.sin_family = af_inet;
target_addr.sin_port = htons(i);
target_addr.sin_addr.s_addr = inet_addr (argv[1]);
cout << "正在掃描埠:" << i << endl;
if (connect (testsocket, (struct sockaddr *) &target_addr, sizeof(struct sockaddr)) == socket_error)
cout << "埠" << i << "關閉!" << endl;
else
{
iopenedport ;
cout << "埠" << i << "開放\n" << endl;
}
}
cout << "目標主機" << argv[1] << "從" << iportfrom << "--" << iportto << "共有" << iopenedport << "個埠開放" << endl;
closesocket (testsocket);
wsacleanup();
}
return 0;
}
vc6.0 下 編譯
c. socket編程是什麼。
socket編程一種獨立於協議的網路編程介面,應用程序可以通過它發送或接收數據,可對其進行像對文件一樣的打開、讀寫和關閉等操作。
socket是應用層與tcp/ip協議族通信的中間軟體抽象層,它是一組介面。在設計模式中,socket其實就是一個門面模式,它把復雜的tcp/ip協議族隱藏在socket介面後面,對用戶來說,一組簡單的介面就是全部,讓socket去組織數據,以符合指定的協議。
(3)socket編程擴展閱讀
套接字可以看成是兩個網路應用程序進行通信時,各自通信連接中的一個端點。通信時,其中的一個網路應用程序將要傳輸的一段信息寫入它所在主機的socket中,該socket通過網路介面卡的傳輸介質將這段信息發送給另一台主機的socket中,使這段信息能傳送到其他程序中。
在網路應用程序設計時,由於tcp/ip的核心內容被封裝在操作系統中,如果應用程序要使用tcp/ip,可以通過系統提供的tcp/ip的編程介面來實現。
參考資料來源:網路-socket
d. socket編程
你的埠號被使用了 換個埠試試
e. socket網路編程
bzero() 函數的功能是將一塊內存清零。
bzero((char *) sendpkt, sizeof (struct udprecord)); 功能是將 sendpkt 指向的內存清零。
和 memset(sendpkt, 0, sizeof(struct udpprecord)); 的功能是一樣的。
f. socket編程
這是我以前學java的時候寫的一個程序,你把那個客戶端地址改成你自己的主機地址試一下,這是我截取的一部分,不知道能不能正常運行
客戶端:
import java.io.*;
import java.net.*;
public class helloclient {
/**
* @param args
*/
public static void main(string[] args) throws ioexception{
// todo auto-generated method stub
socket hellosocket=new socket("22.210.10.143",9999);
string []s=new string [4];
bufferedreader in=new bufferedreader(new inputstreamreader(hellosocket.getinputstream()));
for(int j=0;j<4;j )
s[j]=in.readline();
system.out.println(s[0]);
system.out.println(s[1]);
system.out.println(s[2]);
// in.close();
hellosocket.close();
}
}
伺服器端:
import java.io.*;
import java.net.*;
import org.omg.corba_2_3.portable.outputstream;
public class helloworld {
/**
* @param args
*/
public static void main(string[] args) throws ioexception{
// todo auto-generated method stub
serversocket serversocket=new serversocket(9999);
socket slientsocket=serversocket.accept();
printwriter out=new printwriter(slientsocket.getoutputstream(),true);
out.println("hello world1 !");
out.println("hello world2 !");
out.println("hello world3 !");
slientsocket.close();
serversocket.close();
}
}
g. socket編程 c語言
sender 沒有看到 i 列印,是由於你沒有加換行,由於標准輸出是行緩沖,所以不會馬上列印,而是要等遇到 \n 或者進程結束才會列印。你可以寫成 printf("%d\n"); 就能看到發送方的列印。
接收方也可以加上printf來列印。
這么簡單的程序,用gdb自己調試也可以。
h. socket編程的幾種模式
其基本原理是:首先建立一個socket連接,然後對其進行操作,比如,從該socket讀數據。因為網路傳輸是要一定的時間的,即使網路通暢的情況下,接受數據的操作也要花費時間。對於一個簡單的單線程程序,接收數據的過程是無法處理其他操作的。比如一個窗口程序,當你接收數據時,點擊按鈕或關閉窗口操作都不會有效。它的缺點顯而易見,一個線程你只能處理一個 socket,用來教課還行,實際使用效果就不行了。select模型 為了處理多個socket連接,聰明的人們發明了select模型。該模型以集合來管理socket連接,每次去查詢集合中的socket狀態,從而達到處理多連接的能力,其函數原型是int select(int nfds, fd_set far * readfds, fd_set far * writefds, fd_set far * exceptfds, const struct timeval far * timeout)。比如我們判斷某個socket是否有數據可讀,我們首先將一個fdread集合置空,然後將socket加入到該集合,調用 select(0,&fdread,null,null,null),之後我們判斷socket是否還在fdread中,如果還在,則說明有數據可讀。數據的讀取和阻塞模型相同,調用recv函數。但是每個集合容量都有一個限值,默認情況下是64個,當然你可以重新定義它的大小,但還是有一個最上限,自己設置也不能超過該值,一般情況下是1024。盡管select模型可以處理多連接,但集合的管理多少讓人感到繁瑣。非同步選擇模型 熟悉windows操作系統的都知道,其窗口處理是基於消息的。人們又發明了一種新的網路模型——wsaasyncselect模型,即非同步選擇模型。該模型為每個socket綁定一個消息,當socket上出現事先設置的socket事件時,操作系統就會給應用程序發送這個消息,從而對該 socket事件進行處理,其函數原型是int wsaasynselect(socket s, hwnd hwnd, unsigned int wmsg, long levent)。hwnd指明接收消息的句柄,wmsg指定消息id,levent按位設置感興趣的網路事件,入 wsaasyncselect(s,hwnd,wm_socket, fd_connect | fd_read | fd_close)。該模型的優點是在系統開銷不大的情況下同時處理許多連接,也不需要什麼集合管理。缺點很明顯,即使你的程序不需要窗口,也要專門為 wsaasyncselect模型定義一個窗口。另外,讓單個窗口去處理成千上萬的socket操作事件,很可能成為性能瓶頸。事件選擇模型 與wsaasynselect模型類似,人們還發明了wsaeventselect模型,即事件選擇模型。看名字就可以猜測出來,它是基於事件的。wsaasynselect模型在出現感興趣的socket事件時,系統會發一個相應的消息。而wsaeventselect模型在出現感興趣的socket事件時,系統會將相應wsaevent事件設為傳信。可能你現在對sokect事件和普通wsaevent事件還不是很清楚。 socket事件是與socket操作相關的一些事件,如fd_read,fd_write,fd_accept等。而wsaevent事件是傳統的事件,該事件有兩種狀態,傳信(signaled)和未傳信(non-signaled)。所謂傳信,就是事件發生了,未傳信就是還沒有發生。我們每次建立一個連接,都為其綁定一個事件,等到該連接變化時,事件就會變為傳信狀態。那麼,誰去接受這個事件變化呢?我們通過一個 wsawaitformultipleevents(...)函數來等待事件發生,傳入參數中的事件數組中,只有有一個事件發生,該函數就會返回(也可以設置為所有事件發生才返回,在這里沒用),返回值為事件的數組序號,這樣我們就知道了哪個事件發生了,也就是該事件對應的socket有了socket操作事件。該模型比起wsaasynselect模型的優勢很明顯,不需要窗口。唯一缺點是,該模型每次只能等待64個事件,這一限制使得在處理多 socket時,有必要組織一個線程池,伸縮性不如後面要講的重疊模型。重疊i/o(overlapped i/o)模型重疊i/o(overlapped i/o)模型使應用程序達到更佳的系統性能。重疊模型的基本設計原理是讓應用程序使用重疊數據結構,一次投遞一個或多個winsock i/o請求。重疊模型到底是什麼東西呢?可以與wsaeventselect模型做類比(其實不恰當,後面再說),事件選擇模型為每個socket連接綁定了一個事件,而重疊模型為每個socket連接綁定了一個重疊。當連接上發生socket事件時,對應的重疊就會被更新。其實重疊的高明之處在於,它在更新重疊的同時,還把網路數據傳到了實現指定的緩存區中。我們知道,前面的網路模型都要用戶自己通過recv函數來接受數據,這樣就降低了效率。我們打個比方,wsaeventselect模型就像郵局的包裹通知,用戶收到通知後要自己去郵局取包裹。而重疊模型就像送貨上門,郵遞員發給你通知時,也把包裹放到了你事先指定的倉庫中。 重疊模型又分為事件通知和完成常式兩種模式。在分析這兩種模式之前,我們還是來看看重疊數據結構: typedef struct wsaoverlapped{dword internal; dword internalhigh; dword offset; dword offsethigh; wsaevent hevent; }wsaoverlapped, far * lpwsaoverlapped; 該數據結構中,internal、internalhigh、offset、offsethigh都是系統使用的,用戶不用去管,唯一關注的就是 hevent。如果使用事件通知模式,那麼hevent就指向相應的事件句柄。如果是完成常式模式,hevent設為null。我們現在來看事件通知模式,首先創建一個事件hevent,並創建一個重疊結構acceptoverlapped,並設置acceptoverlapped.hevent = hevent,databuf是我們事先設置的數據緩存區。調用 wsarecv(acceptsocket,&databuf,1,&recvbytes,&flags,&acceptoverlapped,null),則將acceptsocket與acceptoverlapped重疊綁定在了一起。當接收到數據以後,hevent就會設為傳信,而數據就會放到 databuf中。我們再通過wsawaitformultipleevents(...)接收到該事件通知。這里我們要注意,既然是基於事件通知的,那它就有一個事件處理上限,一般為64。 完成常式和事件通知模式的區別在於,當相應的socket事件出現時,系統會調用用戶事先指定的回調函數,而不是設置事件。其實就是將wsarecv的最後一個參數設為函數指針。該回調函數的原型如下: void callback completionroutine( dword dwerror, dword cbtransferred, lpwsaoverlapped lpoverlapped, dword dwflags);其中,cbtransferred表示傳輸的位元組數,lpoverlapped是發生socket事件的重疊指針。我們調用 wsarecv(acceptsocket,&databuf,1,&recvbytes,&flags,&acceptoverlapped,workerroutine) 將acceptsocket與workroutine常式綁定。這里有一點小提示,當我們創建多個socket的連接時,最好把重疊與相應的數據緩存區用一個大的數據結構放到一塊,這樣,我們在常式中通過lpoverlapped指針就可以直接找到相應的數據緩存區。這里要注意,不能將多個重疊使用同一個數據緩存區,這樣在多個重疊都在處理時,就會出現數據混亂。完成埠模型 下面我們來介紹專門用於處理為數眾多socket連接的網路模型——完成埠。因為需要做出大量的工作以便將socket添加到一個完成埠,而其他方法的初始化步驟則省事多了,所以對新手來說,完成埠模型好像過於復雜了。然而,一旦弄明白是怎麼回事,就會發現步驟其實並非那麼復雜。所謂完成埠,實際是windows採用的一種i/o構造機制,除套接字句柄之外,還可以接受其他東西。使用這種模式之前,首先要創建一個i/o完成埠對象,該函數定義如下: handle createiocompletionport( handle filehandle, handle existingcompletionport, dword completionkey, dword numberofconcurrentthreads);該函數用於兩個截然不同的目的:1)用於創建一個完成埠對象。2)將一個句柄同完成埠關聯到一起。 通過參數numberofconcurrentthreads,我們可以指定同時運行的線程數。理想狀態下,我們希望每個處理器各自負責一個線程的運行,為完成埠提供服務,避免過於頻繁的線程任務切換。對於一個socket連接,我們通過 createiocompletionport((handle)accept,completionport, (dword)perhandledata,0)將accept連接與completionport完成埠綁定到一起,competionport對應的那些線程不斷通過getqueuedcompletionstatus來查詢與其關聯的socket連接是否有i/o操作完成,如果有,則做相應的數據處理,然後通過wsarecv將該socket連接再次投遞,繼續工作。完成埠在性能和伸縮性方面表現都很好,相關聯的socket連接數目沒有限制。
i. 什麼是socket編程
socket 就是插座, 你想啊一旦插上插座線路就通了, 信息就可以傳送了, socket攜帶了你要發送的數據。
所謂socket編程, 就是調用系統提供的封裝好的socket api 實現底層的網路通信, 具體的話您可以去看看這個:
http://ke..com/view/13870.htm
j. 如何進行socket編程
創建套接字,綁定本地埠,等待連接,發送數據,關閉套接字