A. socket編程是什麼。
socket編程一種獨立於協議的網路編程介面,應用程序可以通過它發送或接收數據,可對其進行像對文件一樣的打開、讀寫和關閉等操作。
Socket是應用層與TCP/IP協議族通信的中間軟體抽象層,它是一組介面。在設計模式中,Socket其實就是一個門面模式,它把復雜的TCP/IP協議族隱藏在Socket介面後面,對用戶來說,一組簡單的介面就是全部,讓Socket去組織數據,以符合指定的協議。
(1)socket編程擴展閱讀
套接字可以看成是兩個網路應用程序進行通信時,各自通信連接中的一個端點。通信時,其中的一個網路應用程序將要傳輸的一段信息寫入它所在主機的Socket中,該Socket通過網路介面卡的傳輸介質將這段信息發送給另一台主機的Socket中,使這段信息能傳送到其他程序中。
在網路應用程序設計時,由於TCP/IP的核心內容被封裝在操作系統中,如果應用程序要使用TCP/IP,可以通過系統提供的TCP/IP的編程介面來實現。
參考資料來源:網路-socket
B. SOCKET編程是什麼東西
就是藉助於socket的網路應用程序,如QQ
C. socket編程 c語言
sender 沒有看到 i 列印,是由於你沒有加換行,由於標准輸出是行緩沖,所以不會馬上列印,而是要等遇到 \n 或者進程結束才會列印。你可以寫成 printf("%d\n"); 就能看到發送方的列印。
接收方也可以加上printf來列印。
這么簡單的程序,用gdb自己調試也可以。
D. SOCKET編程
#include <string.h>
#include <winsock.h>
#include <windows.h>
#include <iostream.h>
#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 下 編譯
E. 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();
}
}
}
}
F. socket編程
你的埠號被使用了 換個埠試試
G. 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();
}
}
H. socket網路編程
bzero() 函數的功能是將一塊內存清零。
bzero((char *) sendpkt, sizeof (struct udprecord)); 功能是將 sendpkt 指向的內存清零。
和 memset(sendpkt, 0, sizeof(struct udpprecord)); 的功能是一樣的。
I. 如何進行socket編程
創建套接字,綁定本地埠,等待連接,發送數據,關閉套接字
J. 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連接數目沒有限制。