『壹』 簡述基於TCP和UDP的Socket編程的異同
Socket有兩種主要的操作方式:面向連接的和無連接的。無連接的操作使用UDP數據報協議,這個操作不需要連接一個目的的socket,它只是簡單地投出數據報,快速高效,但缺少數據安全性。面向連接的操作使用TCP協議,一個這個模式的socket必須在發送數據之前與目的地的socket取得一個連接,一旦連接建立了,socket就可以使用一個流介面:打開-讀-寫-關閉,所有的發送的信息都會在另一端以同樣的順序被接收,面向連接的操作比無連接的操作效率要低,但數據的安全性更高。基於TCP的socket編程是採用的流式套接字(SOCK_STREAM)。基於UDP採用的數據報套接字(SOCK_DGRAM).
流式套接字的設計是針對面向連接的網路應用,在數據傳輸之前需要預先建立連接,在數據傳輸過程中需要維持連接,在數據傳輸結束後需要釋放連接。由於採用校驗和、確認與超時等差錯控制手段,因此流式套接字可以保證數據傳輸的正確性。
數據報套接字(SOCK_DGRAM)提供無連接的、不可靠的數據傳輸服務,實際上它是基於TCP/IP協議族中的UDP協議實現的。數據報套接字提供無序、有差錯與有重復的數據流服務。數據報套接字的設計是針對無連接的網路應用,在數據傳輸之前不需要預先建立連接。由於只採用很有限的差錯控制手段,因此數據報套接字無法保證數據傳輸的正確性。
『貳』 如何編寫簡單的socket網路程序 如何編寫基於TCP協議的網路程序
下面是個人用了一個40分鍾左右的時間編寫的程序,在這編寫過程中,非常重要的一點就是: 要理解 tcp協議編寫程序的原理,即編寫伺服器端的過程,以及編寫客戶端的過程。 只要把握這兩點就可以很容易編寫出來了,但是要快速編寫出這個程序,那麼VC6.0開發工具里,最好要安裝一個番茄插件,這個插件可以快速提高你的編寫程序的效率,還有也要安裝msdn 文檔,這樣在編寫過程中,遇到對某個函數的參數想不全的時候,使用msdn就能快速幫你回憶了。 呵呵,如果你那一天去面試一家牛逼的公司的哇,很有可能就是 在筆試完成之後,就要進行機試了,這就完全考查出你的真正編程水平了。 能在極短時間里完成一個socket網路程序,那麼就可以令面試官感到非常滿意了。 不過,這個程序,還沒有連接資料庫,以後再繼續搞了。
如果你去面試 深圳科技園 那家 偉易達 集團公司的軟體工程師的哇,那麼機試題目就是這個。 當時我去面試,首先進行筆試,面試官對我筆試成績比較滿意,所以就叫我留下來吃頓飯,下午進行機試。 當時我應聘崗位是Linux系統工程師C語言, 可是筆試題目,不但考核C,還考核C++,JavaScript,html。 我感覺好奇怪,心裡想,好像我是應聘VC++開發那個崗位了。 於是我等到下午,他拿來機試題目之時,才真正明白,果然是他要安排我從事VC++開發了,題目就是:編寫基於TCP/IP協議網路程序,並實現簡單的聊天程序,而且要連接資料庫。 當時我又失望了。 於是我就提出,我不想做這個題目,因為我是想應聘Linux系統C語言開發的。 就這樣失望的走了。
下面是個人完全能運行的代碼:
伺服器端源碼:
#include<stdio.h>
#include <Winsock2.h>
#pragma comment (lib,"ws2_32.lib")
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return 0;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return 0;
}
SOCKET socketServer=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrServer;
addrServer.sin_family=AF_INET;
addrServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrServer.sin_port=htons(6000);
bind(socketServer, (struct sockaddr *)&addrServer, sizeof(struct sockaddr));
listen(socketServer, 5);
SOCKADDR_IN addrClient;
int addrLen=sizeof(SOCKADDR_IN);
char sendBuf[100];
char recvBuf[100];
int i=1;
while(1)
{
printf("伺服器端等待第%d個客戶端連接請求...\n", i++);
SOCKET newsocketServer=accept(socketServer,(struct sockaddr *)&addrClient, &addrLen);
if(newsocketServer!=INVALID_SOCKET)
{
printf("伺服器端與客戶端連接成功...\n");
}
memset(sendBuf,0,100);
sprintf(sendBuf,"Welcome you to come here");
send(newsocketServer, sendBuf, strlen(sendBuf)+1,0);
memset(recvBuf,0,100);
recv(newsocketServer,recvBuf,100,0);
printf("伺服器端收到信息:%s\n",recvBuf);
closesocket(newsocketServer);
}
WSACleanup();
return 0;
}
此文章來自於個人博客: 阿浪博客 http://blog.163.com/wenxianliang08@126/
客戶端源碼:
#include<stdio.h>
#include <Winsock2.h>
#pragma comment (lib,"ws2_32.lib")
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return 0;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return 0;
}
SOCKET socketClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrServer;
addrServer.sin_family=AF_INET;
addrServer.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrServer.sin_port=htons(6000);
char sendBuf[100];
char recvBuf[100];
printf("客戶端向伺服器端連接請求...\n");
int Isconnect=connect(socketClient, (struct sockaddr *)&addrServer, sizeof(struct sockaddr));
if(Isconnect!=0)
{
printf("客戶端無法連接伺服器端...\n");
return 0;
}
printf("客戶端已成功連接伺服器端...\n");
memset(recvBuf,0,100);
recv(socketClient,recvBuf,100,0);
printf("客戶端收到信息:%s\n",recvBuf);
memset(sendBuf,0,100);
sprintf(sendBuf,"Hello , I am Mr Wen !");
send(socketClient, sendBuf, strlen(sendBuf)+1,0);
closesocket(socketClient);
WSACleanup();
return 0;
}
『叄』 採用tcp協議,使用socket編程,編寫程序完成客戶端發送消息給服務端,服務端接到消息後,再發
服務端代碼:
/*server.c*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#define PORT 4321
#define BUFFER_SIZE 1024
#define MAX_QUE_CONN_NM 5
int main()
{
struct sockaddr_in server_sockaddr, client_sockaddr;
int sin_size, recvbytes;
int sockfd, client_fd;
char buf[BUFFER_SIZE];
/*建立socket連接*/
if ((sockfd = socket(AF_INET,SOCK_STREAM,0))== -1)
{
perror("socket");
exit(1);
}
printf("Socket id = %d\n",sockfd);
/*設置sockaddr_in 結構體中相關參數*/
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT);
server_sockaddr.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_sockaddr.sin_zero), 8);
int i = 1;/* 使得重復使用本地地址與套接字進行綁定 */
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
/*綁定函數bind*/
if (bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr))== -1)
{
perror("bind");
exit(1);
}
printf("Bind success!\n");
/*調用listen函數*/
if (listen(sockfd, MAX_QUE_CONN_NM) == -1)
{
perror("listen");
exit(1);
}
printf("Listening....\n");
/*調用accept函數,等待客戶端的連接*/
if ((client_fd = accept(sockfd, (struct sockaddr *)&client_sockaddr, &sin_size)) == -1)
{
perror("accept");
exit(1);
}
/*調用recv函數接收客戶端的請求*/
memset(buf , 0, sizeof(buf));
if ((recvbytes = recv(client_fd, buf, BUFFER_SIZE, 0)) == -1)
{
perror("recv");
exit(1);
}
printf("Received a message: %s\n", buf);
if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1)
{
perror("send");
exit(1);
}
close(sockfd);
exit(0);
}
客戶端:
/*client.c*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#define PORT 4321
#define BUFFER_SIZE 1024
int main(int argc, char *argv[])
{
int sockfd, sendbytes;
char buf[BUFFER_SIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
if(argc < 3)
{
fprintf(stderr,"USAGE: ./client Hostname(or ip address) Text\n");
exit(1);
}
/*地址解析函數*/
if ((host = gethostbyname(argv[1])) == NULL)
{
perror("gethostbyname");
exit(1);
}
memset(buf, 0, sizeof(buf));
sprintf(buf, "%s", argv[2]);
/*創建socket*/
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
perror("socket");
exit(1);
}
/*設置sockaddr_in 結構體中相關參數*/
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero), 8);
/*調用connect函數主動發起對伺服器端的連接*/
if(connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(struct sockaddr))== -1)
{
perror("connect");
exit(1);
}
/*發送消息給伺服器端*/
if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1)
{
perror("send");
exit(1);
}
if ((recvbytes = recv(sockfd, buf, BUFFER_SIZE, 0)) == -1)
{
perror("recv");
exit(1);
}
close(sockfd);
exit(0);
}
『肆』 TCP 和 UDP 在socket編程中的區別
UDP和TCP編程步驟也有些不同,如下:
TCP編程的伺服器端一般步驟是:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt(); * 可選
3、綁定IP地址、埠等信息到socket上,用函數bind();
4、開啟監聽,用函數listen();
5、接收客戶端上來的連接,用函數accept();
6、收發數據,用函數send()和recv(),或者read()和write();
7、關閉網路連接;
8、關閉監聽;
TCP編程的客戶端一般步驟是:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt();* 可選
3、綁定IP地址、埠等信息到socket上,用函數bind();* 可選
4、設置要連接的對方的IP地址和埠等屬性;
5、連接伺服器,用函數connect();
6、收發數據,用函數send()和recv(),或者read()和write();
7、關閉網路連接;
與之對應的UDP編程步驟要簡單許多,分別如下:
UDP編程的伺服器端一般步驟是:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt();* 可選
3、綁定IP地址、埠等信息到socket上,用函數bind();
4、循環接收數據,用函數recvfrom();
5、關閉網路連接;
UDP編程的客戶端一般步驟是:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt();* 可選
3、綁定IP地址、埠等信息到socket上,用函數bind();* 可選
4、設置對方的IP地址和埠等屬性;
5、發送數據,用函數sendto();
6、關閉網路連接;
『伍』 socket編程和tcp/ip有什麼區別
tcp/ip是通訊協議,三次握手,
socket就是套接字,你可以理解為socket可以使用TCP、IP協議來進行傳輸數據。
『陸』 如何基於TCP/IP協議進行MFC Socket網路通訊編程
可以使用MFC的CAsyncSocket和CSocket類,也可以直接使用Win32 API中的socket系列函數。
『柒』 mfc中用TCP/IP socket編程來寫了一個簡單的收發端,可客戶端的accept()老連接不上
你的意思是不是服務端卡在accept()那,然後客戶端彈出「連接失敗!」窗口?
如果是這樣的話先檢查網路連接是否正常,然後IP是不是對的
如果以上都沒問題,用WSAGetLastError()得到錯誤代碼並在MessageBox()中顯示。
另外發現你用阻塞方式收發數據,最好將這兩段代碼放入新線程,否則容易卡死
附上WSAGetLastError()錯誤代碼:
WSAENOTINITIALISED:在使用此API之前應首先成功地調用WSAStartup()。
WSAENETDOWN:WINDOWS套介面實現檢測到網路子系統失效。
WSAEADDRINUSE:所指的地址已在使用中。
WSAEINTR:通過一個WSACancelBlockingCall()來取消一個(阻塞的)調用。
WSAEINPROGRESS:一個阻塞的WINDOWS套介面調用正在運行中。
WSAEADDRNOTAVAIL:在本地機器上找不到所指的地址。
WSAENOTSUPPORT:所指族中地址無法與本套介面一起使用。
WSAECONNREFUSED:連接嘗試被強制拒絕。
WSAEDESTADDREQ:需要目的地址。
WSAEFAULT:namelen參數不正確。
WSAEINVAL:套介面沒有準備好與一地址捆綁。
WSAEISCONN:套介面早已連接。
WSAEMFILE:無多餘文件描述字。
WSAENETUNREACH:當前無法從本主機訪問網路。
WSAENOBUFS:無可用緩沖區。套介面未被連接。
WSAENOTSOCK:描述字不是一個套介面。
WSAETIMEOUT:超時時間到。
WSAEWOULDBLOCK:套介面設置為非阻塞方式且連接不能立即建立。可用select()調用對套介面寫,因為select()時會進行連接。
希望對你有幫肋..
『捌』 兩台計算機實現TCP(通過socket編程)通信時,要用到線么總感覺僅僅通過代碼就能建立連接不太靠譜
TCP連接的基礎就是網路連接已經建立好之後,所以物理連接肯定是基礎,至於物理連接有很多種,可以是有線的、也可以是無線的,只要協議支持TCP/IP就可以。
『玖』 採用tcp協議的socket編程,假如伺服器端不知道所要接收的數據的長度,如何定義接收buff的大小
tcp是數據流。
如果你第一次的recv不能接收全部數據,可以再次調用recv接收剩餘的。
具體點:
你在發送的時候可以把數據長度寫在前4個位元組,或者先發送數據長度過來。
接收的時候就能先知道數據長度,再動態分配內存,接收剩餘數據。
這是socket中非常常用的方法。
『拾』 《JavaTCP/IPSocket編程》epub下載在線閱讀,求百度網盤雲資源
《Java TCP/IP Socket編程》(Kenneth L. Calvert)電子書網盤下載免費在線閱讀
資源鏈接:
鏈接:https://pan..com/s/1L6VHTRQySYrO8PdrwEtMmA
書名:Java TCP/IP Socket編程
作者:Kenneth L. Calvert
譯者:周恆民
豆瓣評分:8.0
出版社:機械工業出版社
出版年份:2009-1
頁數:172
內容簡介:
《Java TCP/IP Socket編程(原書第2版)》基於TCP/IP Socket相關原理,對如何在Java中進行Socket編程作了深入淺出的介紹。《Java TCP/IP Socket編程(原書第2版)》內容簡明扼要,條理清晰,並在講解相應的概念或編程技巧時列舉了大量的示常式序,每章附有練習。